手動實現Promise

// 定義異步調用的主類,名為 MyPromise
class MyPromise {// 執行器接收 resolve 和 reject 方法來改變 promise 的狀態constructor(executor) {// 初始化狀態為 "pending"this.state = "pending";// 初始化值為 undefinedthis.value = undefined;// 初始化原因為 undefinedthis.reason = undefined;// 完成狀態回調函數集this.onResolvedCallbacks = [];// 拒絕狀態回調函數集this.onRejectedCallbacks = [];// 在resolve中為value賦值const resolve = (value) => {//當狀態為pending時進行狀態更改和賦值操作if (this.state === "pending") {this.state = "fulfilled";this.value = value;// 當promise從pending狀態轉為fulfilled,會執行onResolvedCallbacks中的所有回調函數this.onResolvedCallbacks.forEach((fn) => fn());}};// 在reject中為reason賦值const reject = (reason) => {// 當狀態為 pending 時進行狀態更改和賦值操作if (this.state === "pending") {this.state = "rejected";this.reason = reason;// 當promise從pending狀態轉為rejected,會執行onRejectedCallbacks中的所有回調函數this.onRejectedCallbacks.forEach((fn) => fn());}};// 立即執行executor,錯誤則執行rejecttry {executor(resolve, reject);} catch (err) {reject(err);}}// promise 有一個名為 then 的方法,它接受兩個參數:onFulfilled 和 onRejected,然后返回一個新的 promisethen(onFulfilled, onRejected) {// 對處理函數進行判定,如果其為空或者其不是函數,則賦值為默認函數onFulfilled =typeof onFulfilled === "function" ? onFulfilled : (value) => value;onRejected =typeof onRejected === "function"? onRejected: (reason) => {throw reason;};// 返回新的promise對象const promise2 = new MyPromise((resolve, reject) => {if (this.state === "fulfilled") {setTimeout(() => {try {const x = onFulfilled(this.value);this.resolvePromise(promise2, x, resolve, reject);} catch (err) {reject(err);}}, 0);}if (this.state === "rejected") {setTimeout(() => {try {const x = onRejected(this.reason);this.resolvePromise(promise2, x, resolve, reject);} catch (err) {reject(err);}}, 0);}// 當state為pending時,將onFulfilled和onRejected存放起來if (this.state === "pending") {this.onResolvedCallbacks.push(() => {setTimeout(() => {try {const x = onFulfilled(this.value);this.resolvePromise(promise2, x, resolve, reject);} catch (err) {reject(err);}}, 0);});this.onRejectedCallbacks.push(() => {setTimeout(() => {try {const x = onRejected(this.reason);this.resolvePromise(promise2, x, resolve, reject);} catch (err) {reject(err);}}, 0);});}});return promise2;}// 對不同情況的x進行處理resolvePromise(promise2, x, resolve, reject) {// promise 和 x 引用同一對象,錯誤處理if (promise2 === x) {return reject(new TypeError("Chaining cycle detected for promise"));}let called = false;if (x instanceof MyPromise) {x.then((value) => {if (called) return;called = true;this.resolvePromise(promise2, value, resolve, reject);},(reason) => {if (called) return;called = true;reject(reason);});} else {resolve(x);}}// 返回一個完成狀態的promisestatic resolve(value) {return new MyPromise((resolve, reject) => {resolve(value);});}// 返回一個拒絕狀態的promisestatic reject(reason) {return new MyPromise((resolve, reject) => {reject(reason);});}// 返回一個 Promise 實例,該實例在 iterable 參數內所有的 promise 都“完成(Fulfilled)”或參數中不包含 promise 時回調完成(resolve)static all(promises) {return new MyPromise((resolve, reject) => {const result = [];let count = 0;const processResult = (index, value) => {result[index] = value;count++;// 所有結果都得到了則更新狀態為fulfilledif (count === promises.length) {resolve(result);}};// 使用 forEach,能遍歷到不是promise的其他類型promises.forEach((promise, index) => {if (promise instanceof MyPromise) {promise.then((value) => processResult(index, value),(reason) => reject(reason));} else {processResult(index, promise);}});});}// 返回一個 Promise 實例,只有當 iterable 參數內的某個 promise 成功或失敗時,返回的 promise 才會異步地 success 或 failurestatic race(promises) {return new MyPromise((resolve, reject) => {promises.forEach((promise) => {if (promise instanceof MyPromise) {promise.then(resolve, reject);} else {resolve(promise);}});});}
}

調用舉例

// 創建一個 Promise 對象
const promise = new MyPromise((resolve, reject) => {// 異步操作,比如網絡請求或者定時器setTimeout(() => {// 異步操作成功,調用 resolve 并傳遞結果resolve('成功');// 或者異步操作失敗,調用 reject 并傳遞錯誤原因// reject('失敗');}, 1000);
});// 使用 then 方法添加成功和失敗的回調函數
promise.then(value => {console.log('成功的結果:', value);},reason => {console.log('失敗的原因:', reason);}
);

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/13075.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/13075.shtml
英文地址,請注明出處:http://en.pswp.cn/web/13075.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

鏡像抑制和鏡像衰減有什么不同

在很多無線產品接收機手冊中,我們會看到兩個參數,一個是鏡像抑制(Image Rejection),另一個是鏡像衰減(Image Attention),但這兩者究竟有什么不同,一直比較疑惑&#xff0…

AI學習指南線性代數篇-奇異值分解

AI學習指南線性代數篇-奇異值分解 一、概述 在人工智能領域,線性代數是一項非常重要的基礎知識,而奇異值分解(Singular Value Decomposition, SVD)作為線性代數中的一種重要工具,被廣泛應用于機器學習、數據科學等領…

理解Spring的IOC核心:為何它成為開發中的關鍵要素?

Spring框架采用的IOC(依賴注入)技術,是一種創新的設計思路,它授權程序開發人員將組件實例化及生命周期管理的職責轉交給框架自身處理。在這一機制下,Spring框架負責協調并裝配應用程序中的各個組件,從而實現…

以太坊Layer 2開發商StarkWare

文章目錄 以太坊Layer 2開發商StarkWare相關新聞StarkWare是什么團隊介紹StarkEx 和 StarkNet參考以太坊Layer 2開發商StarkWare 相關新聞 據The Block 2021年11月16日消息,使用ZK-rollups技術的以太坊第2層開發商StarkWare在C輪融資中籌集了5000萬美元,其估值已達20億美元…

三路輸出小功率開關電源【MATLAB/simulink】

擬選用一種DC-DC變換器拓撲使用1700 V SiC MOSFET或IGBT設計三相功率系 統的高頻開關直流輔助電源,它可用于太陽能逆變器、工業開關電源、電動汽車充電器、 電機驅動裝置等領域。(建議采用單端反激式電路拓撲,開關頻率為80kHz) 電路基本參數&…

【Unity學習筆記】第十七 Quaternion 中 LookRotation、Lerp、Slerp、RotateTowards等方法辨析與驗證

轉載請注明出處: https://blog.csdn.net/weixin_44013533/article/details/138909256 作者:CSDN|Ringleader| 目錄 Quaternion API 速覽FromToRotation在Transform中的應用LookRotation 中upwards取Vector3.up和 transform.up的區別旋轉時如何保持Y軸不變&#xff…

leetcode題目45

跳躍游戲Ⅱ 中等 給定一個長度為 n 的 0 索引整數數組 nums。初始位置為 nums[0]。 每個元素 nums[i] 表示從索引 i 向前跳轉的最大長度。換句話說&#xff0c;如果你在 nums[i] 處&#xff0c;你可以跳轉到任意 nums[i j] 處: 0 < j < nums[i] i j < n 返回到達 n…

戰網國際服怎么下載 暴雪戰網一鍵下載安裝圖文教程

戰網國際版&#xff0c;或稱為Battle.net全球版&#xff0c;是暴雪娛樂構建的一項跨越國界的綜合游戲交流平臺&#xff0c;它無視地理限制&#xff0c;旨在服務全球每一個角落的游戲愛好者。不同于地區專屬版本&#xff0c;國際版為玩家開啟了一扇無門檻的大門&#xff0c;讓每…

org.springframework.jdbc.BadSqlGrammarException

Cause: java.sql.SQLSyntaxErrorException: Table ‘web.emp’ doesn’t exist 產生原因&#xff1a;web表找不到&#xff0c;所以可能數據庫配置錯誤 spring.datasource.urljdbc:mysql://localhost:3306/web02 更改完成后運行成功

音頻筑基:100字說清哈曼曲線的Why和What

音頻筑基&#xff1a;100字說清哈曼曲線的Why和What 本文為短小精悍的音頻小知識總結&#xff0c;希望有用。 Why 音箱等大型外放設備是沒有哈曼曲線的哈曼曲線是為了解決近耳設備如耳機/助聽器&#xff0c;重放聲音時與聲源實際發聲舉例產生的聽感做衰減匹配也即沒有耳機的重…

免費利器:會議之眼一鍵生成論文功能火爆上線 助你快速起航

會議之眼 快訊 親愛的會議之眼粉絲們&#xff0c;你們是否曾經為了寫論文而徹夜苦思冥想&#xff1f;是否曾經為了找資料而焦頭爛額&#xff1f; 今天小編帶來了一個令人興奮的消息&#xff0c;那就是會議之眼網頁端平臺的全新功能——“一鍵生成論文”已經重磅上線啦&#x…

【計算機畢業設計】springboot房地產銷售管理系統的設計與實現

相比于以前的傳統手工管理方式&#xff0c;智能化的管理方式可以大幅降低房地產公司的運營人員成本&#xff0c;實現了房地產銷售的 標準化、制度化、程序化的管理&#xff0c;有效地防止了房地產銷售的隨意管理&#xff0c;提高了信息的處理速度和精確度&#xff0c;能夠及時、…

STM32-09-IWDG

文章目錄 STM32 IWDG1. IWDG2. IWDG框圖3. IWDG寄存器4. IWDG寄存器操作步驟5. IWDG溢出時間計算6. IWDG配置步驟7. 代碼實現 STM32 IWDG 1. IWDG IWDG Independent watchdog&#xff0c;即獨立看門狗&#xff0c;本質上是一個定時器&#xff0c;這個定時器有一個輸出端&#…

mmdetection訓練(1)voc格式的數據集(自制)

mmdetection訓練&#xff08;1&#xff09;voc格式的數據集&#xff08;自制&#xff09; 提前準備一、voc數據集二、修改配置代碼進行訓練&#xff08;敲黑板&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff09;1.數據集相關內容修改2.自定義配置文件構…

云曦實驗室期中考核題

Web_SINGIN 解題&#xff1a; 點擊打開環境&#xff0c;得 查看源代碼&#xff0c;得 點開下面的超鏈接&#xff0c;得 看到一串base64編碼&#xff0c;解碼得flag 簡簡單單的文件上傳 解題&#xff1a; 點擊打開環境&#xff0c;得 可以看出這是一道文件上傳的題目&#x…

【if條件、for循環、數據框連接、表達矩陣畫箱線圖】

編程能力&#xff0c;就是解決問題的能力&#xff0c;也是變優秀的能力 From 生物技能樹 R語言基礎第七節 文章目錄 1.長腳本管理方式if(F){....}分成多個腳本&#xff0c;每個腳本最后保存Rdata&#xff0c;下一個腳本開頭清空再加載 2.實戰項目的組織方式方法&#xff08;一&…

圓上點云隨機生成(人工制作模擬數據)

1、背景介紹 實際上,很多地物外表形狀滿足一定的幾何形狀結構,如圓形是作為常見一類。那么獲取該類目標的點云數據便是位于一個圓上的點云數據。如下圖所示為兩簇典型的點云,其中一種為理想型,點均位于一個圓上,另外一簇則是近似位于一個圓上,這種更加符合真實情況。有時…

好煩啊,我真的不想寫增刪改查了!

大家好&#xff0c;我是程序員魚皮。 很想吐槽&#xff1a;我真的不想寫增刪改查這種重復代碼了&#xff01; 大學剛做項目的時候&#xff0c;就在寫增刪改查&#xff0c;萬萬沒想到 7 年后&#xff0c;還在和增刪改查打交道。因為增刪改查是任何項目的基礎功能&#xff0c;每…

性能測試工具—jmeter的基礎使用

1.Jmeter三個重要組件 1.1線程組的介紹&#xff1a; 特點&#xff1a; 模擬用戶&#xff0c;支持多用戶操作多個線程組可以串行執行&#xff0c;也可以并行執行 線程組的分類&#xff1a; setup線程組&#xff1a;前置處理&#xff0c;初始化普通線程組&#xff1a;編寫…

springboot+vue+mybatis物業管理系統+PPT+論文+講解+售后

快速發展的社會中&#xff0c;人們的生活水平都在提高&#xff0c;生活節奏也在逐漸加快。為了節省時間和提高工作效率&#xff0c;越來越多的人選擇利用互聯網進行線上打理各種事務&#xff0c;通過線上物業管理系統也就相繼涌現。與此同時&#xff0c;人們開始接受方便的生活…