App下載

Promises: JavaScript異步編程的救星

資深網(wǎng)絡(luò)表情包傳播者 2024-04-08 10:11:02 瀏覽數(shù) (906)
反饋

Promises(承諾)是JavaScript中處理異步操作的一種機(jī)制,它提供了一種更優(yōu)雅和可讀性更高的方式來處理異步代碼。Promises的實(shí)現(xiàn)原理基于一種稱為"Promise/A+"規(guī)范的約定,該規(guī)范定義了Promises的行為和接口。

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


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

  1. Promise有3種狀態(tài):pending、fulfilled和rejected。初始狀態(tài)為pending。
  2. Promise實(shí)例包含一個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)。

當(dāng)我們new一個Promise時,會傳入一個執(zhí)行器executor,執(zhí)行器會立即執(zhí)行。在執(zhí)行器中我們可以處理異步任務(wù),比如發(fā)送ajax請求,一旦異步任務(wù)執(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),從而實(shí)現(xiàn)異步流程的控制。

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

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

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

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

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

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

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

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

正確的做法是,在executor函數(shù)中,無論異步任務(wù)是否成功,都需要在最后調(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,將導(dǎo)致Promise永遠(yuǎn)pending,然后注冊的回調(diào)函數(shù)也就不會執(zhí)行。這違反Promise的設(shè)計(jì)初衷,應(yīng)該避免這樣使用。


0 人點(diǎn)贊