首頁  >  文章  >  web前端  >  JavaScript 回呼中的控制反轉:為什麼 Promise 是答案

JavaScript 回呼中的控制反轉:為什麼 Promise 是答案

WBOY
WBOY原創
2024-08-09 06:33:02686瀏覽

回呼函數是作為參數傳遞到另一個函數的函數,然後在外部函數內部呼叫函數以完成某種例程或操作。可以透過兩種方式呼叫回呼:同步和非同步。它是 Javascript 中最基本的非同步模式。

例如:

Inversion of Control in JavaScript Callbacks: Why Promises are the Answer

AB 現在發生,在主 JS 程式的直接控制下。但是 C 被推遲到稍後發生,並在另一方的控制下,在本例中是 ajax(..) 函數。從基本意義上講,這種控制權的交接通常不會為程式帶來很多問題。

但是,頻率不高並不足以忽略問題或問題。事實上,這是回調驅動設計的主要問題之一。它圍繞著這樣一個想法:有時 ajax(..) 或您傳遞回調延續的「一方」不是您編寫的函數,也不是您直接控制的函數。很多時候它是一些第三方提供的實用程式。

當您參與程序並將其執行控制權交給另一個第三方時,我們稱之為「控制反轉」。您的程式碼和第三方實用程式之間存在一個不言而喻的「合約」—一系列您希望維護的內容。

「控制反轉」有什麼問題?

有一個例子可以幫助您更好地理解這個問題。

假設您正在為您的公司建立一個旅遊預訂網站。您新增了一個使用第三方函式庫的 createBooking() 函數的「立即預訂」按鈕。此函數處理預訂,然後呼叫您的回呼以向客戶發送確認電子郵件。

此程式碼可能如下所示:

Inversion of Control in JavaScript Callbacks: Why Promises are the Answer

測試期間一切正常。人們開始在您的網站上預訂旅遊套餐,每個人都對您的工作感到滿意。突然有一天,你接到老闆的電話,問一個重大問題。一位顧客預訂了套餐,並在一次預訂中收到四封相同的確認電子郵件。

您開始除錯問題。您查看發送確認電子郵件的程式碼部分,一切似乎都是正確的。然後,您進一步調查,發現第三方庫中的 createBooking() 實用程式呼叫了您的回呼函數四次,導致發送了四封確認電子郵件。

您聯絡第三方圖書館的支援團隊並說明情況。他們告訴您,他們以前從未遇到過這個問題,但會優先考慮該問題並回覆您。一天后,他們會回電給您並告知他們的調查結果。他們發現一段不應該上線的實驗性程式碼導致 createBooking() 函數多次呼叫回呼。

問題在他們這邊,他們向您保證問題已解決。他們對造成的麻煩表示歉意,並確認問題不會再次發生。

為了防止在尋求解決方案後出現任何不必要的問題,您可以實現一個簡單的 if 語句,如下所示,團隊對此似乎很滿意:

Inversion of Control in JavaScript Callbacks: Why Promises are the Answer

但隨後一位 QA 工程師問道:「如果他們從不呼叫回調會發生什麼?」哎呀。你們誰都沒想到這一點!

您開始考慮他們呼叫您的回呼時可能出現的所有問題。以下是一些問題的清單:

  • 過早呼叫回呼

  • 呼叫回調太晚了(或完全不呼叫)

  • 呼叫回調的次數太少或太多(如上例的問題)

  • 吞下可能發生的任何錯誤/異常

  • ...

您可能會意識到,您必須在程式碼中針對不同情況實現許多解決方案,這將使程式碼變得糟糕且骯髒,因為傳遞給實用程式的每個回調都需要它。

承諾

如果我們能夠反轉控制反轉會怎麼樣?如果我們不是將程式的延續傳遞給另一方,而是期望它返回給我們一種能力,讓我們知道其任務何時完成,然後我們的程式碼可以決定下一步要做什麼?

Promise 提供了一種強大的方法來處理 JavaScript 中的非同步操作,解決回調地獄和控制反轉等問題。與回呼不同,Promises 可讓您管理非同步任務,而無需放棄對程式碼的控制。

考慮在速食店點一個起司漢堡。您將收到一張收據,這是對您未來的起司漢堡的承諾。在等待的同時,您可以做其他事情,因為您知道最終會收到訂單。同樣,JavaScript 中的 Promise 代表一個未來的價值,讓你的程式碼順利進行。

Promise 也會優雅地處理失敗,就像餐廳的起司漢堡用完時你可能會收到通知一樣。這種結構使您的程式碼更具可讀性和可維護性。

我不會在這裡深入探討 Promise,但是透過使用它們,您可以編寫更乾淨、更可靠的非同步程式碼,從而提高 JavaScript 應用程式的整體品質。

例如,對於我們之前描述的旅行預訂網站,如果第三方實用程式返回一個承諾,我們可以這樣處理:

Inversion of Control in JavaScript Callbacks: Why Promises are the Answer

一旦 Promise 被解決(成功完成),它就會永遠保持這種狀態——此時它就成為一個不可變的值,然後可以根據需要多次觀察。這意味著已解決的承諾,其已解決的值可以在程式碼中多次存取或使用,而不會影響其狀態。這使您可以在應用程式的各個部分處理非同步操作的結果,而不必擔心 Promise 更改或重新評估。

Promise 是針對僅回呼程式碼中發生的控制反轉問題的解決方案。回調代表控制反轉。所以反轉回調模式其實是反轉的反轉,或者說控制的反反轉。將控制權恢復到我們最初希望的呼叫程式碼。

參考

  • 你不知道 JS:凱爾辛普森 (Kyle Simpson) 的非同步與表現

  • developer.mozilla.org

以上是JavaScript 回呼中的控制反轉:為什麼 Promise 是答案的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn