JavaScript 以其非同步特性而聞名,可以在不阻塞其他進程的情況下實現資料擷取、動畫和檔案處理等操作。 Promise 是優雅地處理非同步操作的核心,讓我們的程式碼更乾淨、更容易管理。這個專案 XPromise 是 JavaScript Promise 的自訂實現,幫助我們探索 Promise 機制的內部運作原理。
您可以在 GitHub 上查看完整的實作。
什麼是承諾?
JavaScript 中的 Promise 是一個特殊的對象,表示非同步操作的最終完成或失敗。使用 Promises,我們可以將操作排隊以在任務完成後運行,即使我們不知道任務何時完成。以下是 Promise 的獨特之處:
- 三種狀態:Promise 可以是 待處理、已履行 或已拒絕。
- 不可變的狀態變化:一旦 Promise 被解決(履行或拒絕),它就無法更改狀態。
- 與 .then 和 .catch 連結:Promise 提供 .then() 來處理已實現的值,並提供 .catch() 來處理錯誤,使它們可組合。
為什麼要建立自訂承諾?
建立自訂 Promise,如 XPromise,可以更深入地了解其內部工作原理:
- 狀態管理:我們以確保只有一個最終狀態的方式來處理狀態。
- 回呼隊列:Promise 必須將回呼排隊,以便在解析後執行。
- 錯誤處理:它包括一種優雅地處理非同步錯誤的方法,模擬原生 Promise 行為。
項目演練
讓我們瀏覽一下 XPromise 的程式碼,探索使其像 JavaScript 的原生 Promises 一樣運作的每個元件。
設定狀態和基本結構
XPromise 先定義三種狀態:PENDING、FULFILLED 和 REJECTED。
const PENDING = "PENDING"; const FULFILLED = "FULFILLED"; const REJECTED = "REJECTED"; class XPromise { constructor(executor) { this.state = PENDING; this.queue = []; doResolve(this, executor); } // ... }
-
建構子與初始設定:
- XPromise 接受一個執行器函數,該函數會立即運作。
- this.state 追蹤目前狀態,而 this.queue 保存透過 .then() 呼叫排隊的所有函數。
新增 then、catch 和finally 方法
透過then、catch和finally,我們處理完成、拒絕和清理場景。 XPromise 實作連結的方式如下:
const PENDING = "PENDING"; const FULFILLED = "FULFILLED"; const REJECTED = "REJECTED"; class XPromise { constructor(executor) { this.state = PENDING; this.queue = []; doResolve(this, executor); } // ... }
- then:then 方法建立一個新的 XPromise 實例並將其與 onFulfilled 和 onRejected 回呼一起儲存。這可確保鏈中的下一個 Promise 接收前一個 Promise 的輸出。
- catch:處理錯誤的簡寫,相當於呼叫 then(null, onRejected)。
- finally:處理無論 Promise 結果如何都會執行的清理操作。
使用句柄管理已解決的狀態
handle 函數決定 Promise 是否仍有待處理或已解決。如果它處於待處理狀態,則處理程序將添加到佇列中以供稍後執行。如果 Promise 得到解決,它會立即處理處理程序。
then(onFulfilled, onRejected) { const promise = new XPromise(() => {}); handle(this, { promise, onFulfilled, onRejected }); return promise; } catch(onRejected) { return this.then(null, onRejected); } finally(onFinally) { return this.then(onFinally, onFinally); }
解決和拒絕承諾
履行和拒絕的 Promise 需要特殊的函數來處理其結果。 XPromise 是如何實現這一目標的:
function handle(promise, handler) { while (promise.state !== REJECTED && promise.value instanceof XPromise) { promise = promise.value; } if (promise.state === PENDING) { promise.queue.push(handler); } else { handleResolved(promise, handler); } }
-
履行與拒絕:
- 履行和拒絕最終確定 Promise,更新其狀態和值。
- 如果 value 是 Promise 或 thenable,我們會推遲 doResolve 以確保它得到正確處理。
-
完成排隊處理程序:
- 一旦 Promise 解決,finale 就會遍歷佇列以依序執行所有處理程序。
執行器函數 doResolve
doResolve 函數透過包裝解析和拒絕呼叫來安全地運行執行器,防止多次呼叫它們時發生任何進一步的狀態變更。
function fulfill(promise, value) { if (value === promise) { return reject(promise, new TypeError()); } if (value && (typeof value === "object" || typeof value === "function")) { let then; try { then = value.then; } catch (e) { return reject(promise, e); } if (typeof then === "function") { return doResolve(promise, then.bind(value)); } } promise.state = FULFILLED; promise.value = value; finale(promise); } function reject(promise, reason) { promise.state = REJECTED; promise.value = reason; finale(promise); }
XPromise 的用法範例
現在我們有了一個可以運行的 XPromise,讓我們用一個簡單的範例來嘗試:
function doResolve(promise, executor) { let called = false; function wrapFulfill(value) { if (called) return; called = true; fulfill(promise, value); } function wrapReject(reason) { if (called) return; called = true; reject(promise, reason); } try { executor(wrapFulfill, wrapReject); } catch (e) { wrapReject(e); } }
重點
從頭開始重新實作 Promise 提供了有關如何在 JavaScript 中管理非同步程式設計的實作見解:
- 狀態管理確保Promise僅解決一次,保持履行或拒絕。
- 回呼隊列允許有效處理多個鍊式.then()呼叫。
- 錯誤處理使用catch,最終有助於優雅地處理非同步錯誤。
要深入了解程式碼,請查看 GitHub 上的 XPromise 專案。試驗程式碼並隨意自訂它以探索更高級的功能,例如 Promise 競爭條件、連結和嵌套!
以上是建構 XPromise:深入研究自訂 JavaScript Promise的詳細內容。更多資訊請關注PHP中文網其他相關文章!

JavaScript字符串替換方法詳解及常見問題解答 本文將探討兩種在JavaScript中替換字符串字符的方法:在JavaScript代碼內部替換和在網頁HTML內部替換。 在JavaScript代碼內部替換字符串 最直接的方法是使用replace()方法: str = str.replace("find","replace"); 該方法僅替換第一個匹配項。要替換所有匹配項,需使用正則表達式並添加全局標誌g: str = str.replace(/fi

簡單JavaScript函數用於檢查日期是否有效。 function isValidDate(s) { var bits = s.split('/'); var d = new Date(bits[2] '/' bits[1] '/' bits[0]); return !!(d && (d.getMonth() 1) == bits[1] && d.getDate() == Number(bits[0])); } //測試 var

本文探討如何使用 jQuery 獲取和設置 DOM 元素的內邊距和外邊距值,特別是元素外邊距和內邊距的具體位置。雖然可以使用 CSS 設置元素的內邊距和外邊距,但獲取準確的值可能會比較棘手。 // 設定 $("div.header").css("margin","10px"); $("div.header").css("padding","10px"); 你可能會認為這段代碼很

本文探討了十個特殊的jQuery選項卡和手風琴。 選項卡和手風琴之間的關鍵區別在於其內容面板的顯示和隱藏方式。讓我們深入研究這十個示例。 相關文章:10個jQuery選項卡插件

發現十個傑出的jQuery插件,以提升您的網站的活力和視覺吸引力!這個精選的收藏品提供了不同的功能,從圖像動畫到交互式畫廊。讓我們探索這些強大的工具:相關文章:1

HTTP-Console是一個節點模塊,可為您提供用於執行HTTP命令的命令行接口。不管您是否針對Web服務器,Web Serv

本教程向您展示瞭如何將自定義的Google搜索API集成到您的博客或網站中,提供了比標準WordPress主題搜索功能更精緻的搜索體驗。 令人驚訝的是簡單!您將能夠將搜索限制為Y

當div內容超出容器元素區域時,以下jQuery代碼片段可用於添加滾動條。 (無演示,請直接複製到Firebug中) //D = document //W = window //$ = jQuery var contentArea = $(this), wintop = contentArea.scrollTop(), docheight = $(D).height(), winheight = $(W).height(), divheight = $('#c


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

Atom編輯器mac版下載
最受歡迎的的開源編輯器

Dreamweaver Mac版
視覺化網頁開發工具

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。