App下載

Promises的實現(xiàn)原理是什么?

一語呢喃醉 2023-10-02 14:02:00 瀏覽數(shù) (1148)
反饋

Promises的實現(xiàn)原理是什么?


Promises的實現(xiàn)原理可以通過以下4步概括:

  1. Promise有3種狀態(tài):pending、fulfilled和rejected。初始狀態(tài)為pending。
  2. Promise實例包含一個then方法,then方法接受兩個參數(shù):onFulfilled和onRejected,分別為promise成功或失敗的回調(diào)。
  3. Promise有一個內(nèi)部屬性[[PromiseState]],初始值為pending。內(nèi)部又有一個屬性[[PromiseResult]],初始值為undefined。
  4. Promise的狀態(tài)只能從pending到fulfilled或rejected,狀態(tài)一旦改變就不能再變。 fulfilled和rejected狀態(tài)都會觸發(fā)then里的回調(diào)。

當我們new一個Promise時,會傳入一個執(zhí)行器executor,執(zhí)行器會立即執(zhí)行。在執(zhí)行器中我們可以處理異步任務,比如發(fā)送ajax請求,一旦異步任務執(zhí)行結(jié)束,就可以決定是resolve(成功)還是reject(失敗)這個promise。

如果執(zhí)行resolve,那么將[[PromiseState]]設(shè)為fulfilled,[[PromiseResult]]設(shè)為傳入的值。執(zhí)行onFulfilled回調(diào)。

如果執(zhí)行reject,那么將[[PromiseState]]設(shè)為rejected,[[PromiseResult]]設(shè)為傳入的reason。執(zhí)行onRejected回調(diào)。

這樣通過狀態(tài)和結(jié)果的改變,來觸發(fā)then里不同的回調(diào),從而實現(xiàn)異步流程的控制。

Promise就是通過狀態(tài)改變來觸發(fā)回調(diào)的,這也是它實現(xiàn)異步編程的基石。

如果在Promise的執(zhí)行器函數(shù)(executor)中不調(diào)用resolve或reject, 會怎么樣?

如果在Promise的執(zhí)行器函數(shù)(executor)中不調(diào)用resolve或reject,通常會導致兩個結(jié)果:

  • Promise對象的狀態(tài)永遠保持pending

Promise對象代表一個異步操作,它的最終狀態(tài)應該在某個時刻確定下來(fulfilled或rejected)。如果executor函數(shù)中不調(diào)用resolve或reject,Promise的狀態(tài)就無法得以確定,會永遠處于pending狀態(tài)。

  • then方法指定的回調(diào)函數(shù)不會被調(diào)用

then方法注冊的回調(diào)函只有在Promise狀態(tài)確定后才會被調(diào)用,如果狀態(tài)一直是pending,那么then方法的回調(diào)函數(shù)就永遠不會被執(zhí)行。

所以,如果在executor函數(shù)中不調(diào)用resolve或reject,就是一個錯誤的實現(xiàn),違反了Promise/A+規(guī)范。

正確的做法是,在executor函數(shù)中,無論異步任務是否成功,都需要在最后調(diào)用resolve或者reject,將Promise的狀態(tài)確定下來,以便觸發(fā)then方法注冊的回調(diào)。通常like這樣:

new Promise((resolve, reject) => { // ...做一些異步操作 if(成功) { resolve(value); } else { reject(error); } })

所以,不調(diào)用resolve/reject,將導致Promise永遠pending,然后注冊的回調(diào)函數(shù)也就不會執(zhí)行。這違反Promise的設(shè)計初衷,應該避免這樣使用。


0 人點贊