Promise的簡單實現

2022-02-13 12:07:51 字數 4063 閱讀 4691

promise 是非同步程式設計的一種解決方案:從語法上講,promise是乙個物件,從它可以獲取非同步操作的訊息;從本意上講,它是承諾,承諾它過一段時間會給你乙個結果。promise有三種狀態:pending(等待態),fulfiled(成功態),rejected(失敗態);狀態一旦改變,就不會再變。創造promise例項後,它會立即執行。

promises/a+規範原文:

構建promise類

進行初始化,設定status為pending,data和err都為undefined,設定兩個函式resolve和reject傳遞資料,executor預設先執行一次,具體流程看**

constructor

(executor)

}/* 失敗 */

letreject

= err =>

}/* 預設執行一次 */

trycatch(e

)}

通過獲取data/err的方式傳遞資料給then的兩個函式,實現同步情況下的then函式功能

then

(onfulfilled, onrejected)

/* rejected狀態說明this.err已經賦值,直接傳參即可 */if(

this

.status ===

'rejected'

)}

// 示例:

let p =

newpromise

((resolve, reject)

=>)p.

then

( data =>`)

},err =>`)

});// 結果:err->hello

根據發布訂閱的原理,陣列儲存**函式,等待非同步執行resolve/reject再觸發**函式,實現非同步情況下的then函式功能

class

promise

}/* 失敗 */

letreject

= err =>

}//省略...

}then

(onfulfilled, onrejected)

)this

.onrejected_cbs.

push((

)=>)}

}}

// 示例:

let p =

newpromise

((resolve, reject)

=>

,3000)}

)p.then

( data =>`)

},err =>`)

});// 結果:err->hello

實現then函式的鏈式呼叫

(1)實現每個then函式執行後返回乙個新的promise物件nextpromise,只有這樣才能不斷產生和執行新的then函式

(2)記錄當前then裡面兩個**的返回值,返回值即可能是普通值也可能是promise物件,需要將其處理成為普通值再傳給nextpromise

a.當then兩個**為空或者不是函式時,設定預設函式

b.為了解決物件未建立完成前無法對其進行賦值的問題,我們需要將處理的過程放到乙個非同步api裡面,採用非同步方式對nextpromise賦值

then

(onfulfilled, onrejected)

;/* 建立新物件 */

let nextpromise =

newpromise1

((resolve, reject)

=>

catch(e

)})}

/* rejected狀態說明this.err已經賦值,直接傳參即可 */if(

this

.status ===

'rejected'))

}/* 當為pending態時,將**存入對應陣列,等待非同步執行完再依次觸發 */if(

this

.status ===

'pending'))

})this

.onrejected_cbs.

push((

)=>)}

)}})

return nextpromise;

}

(3)對res的型別進行檢測並處理,對promise向下遞迴直到res為普通型別後傳遞給nextpromise,設定called防止測試出現錯誤。

let

resolvepromise

=(nextpromise, res, resolve, reject)

=>

/* 判斷是物件或者函式 */if(

typeof res ===

'object'

&& res !==

null

||typeof res ===

'function'

), err =>)}

else

}catch(e

)}else

/* 普通型別直接返回 */

}

// 示例:

let p =

newpromise

((resolve, reject)

=>

)let p2 = p.

then

(data =>`)

;return

newpromise

((resolve, reject)

=>)}

)}, err => console.

log(

`err->$`

))p2.then

(data => console.

log(

`data2->$`

),err => console.

log(

`err2->$`

))// 結果:data->hello err2->999

使用promises-aplus-tests庫並進行測試

安裝:npm install promises-aplus-tests -g

執行:promises-aplus-tests 當前js檔案路徑

promise.defer = promise.

deferred

=function()

; dfd.promise =

newpromise

((resolve, reject)

=>

)return dfd;

}module.exports = promise;

實現promise.all(),遍歷傳入的任務陣列,若為promise物件,則執行then函式存返回值,若為普通值,直接存入要傳回的陣列。

function

ispromise

(p)}

return

false;}

promise.

all=

(tasks)

=>

}for

(let i =

0; i < tasks.length; i++

)else}}

)}

//示例:

function

say(str)

promise.

all([1

,2,3

,say

('hello'),

5,6,

7,say(

'bye')]

).then

(data => console.

log(data)

, err => console.

log(err)

)// [ 1, 2, 3, 'hello', 5, 6, 7, 'bye' ]

其他功能有時間再寫…

簡單promise實現原理

promise可以有三種狀態,分別是pedding fulfilled rejected pending promise物件例項建立時候的初始狀態 fulfilled 可以理解為成功的狀態 rejected可以理解為失敗的狀態 構造乙個promise例項需要給promise建構函式傳入乙個函式。傳入...

簡單實現Promise原理

const pending pending const resolved resolved const rejected rejected 對於不太經常更改的變數 定於為常量 function mypromise fn function reject value trycatch e mypromi...

Promise原理 簡單實現

參考 個人認為原博的實現有點問題 在next函式的實現上,會導致無限的呼叫 看看一般promise的用法 promise new promise function resolve,reject then function val functioin err then function val fun...