成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

關于 Promise 的執(zhí)行順序

開發(fā) 前端
我們知道,Promise 實例化時,傳入的回調(diào)會立即執(zhí)行,而Promise 的 then 回調(diào)會被放到微任務隊列中,等待執(zhí)行。

最近看到一個 Promise 相關的很有意思的代碼:

new Promise((resolve) => {
console.log(1)
resolve()
}).then(() => {
new Promise((resolve) => {
console.log(2)
resolve()
}).then(() => {
console.log(4)
})
}).then(() => {
console.log(3)
})

第一次看到這個代碼的時候,以為的輸出結(jié)果會是:1,2,3,4,但是被實際的輸出結(jié)果打臉 。

如圖所示,實際的輸出結(jié)果為:1,2,4,3。

代碼分析

為了搞清楚實際的輸出結(jié)果為什么是:1,2,4,3,我們來一步步分析代碼的執(zhí)行。

我們知道,Promise 實例化時,傳入的回調(diào)會立即執(zhí)行,而Promise 的 then 回調(diào)會被放到微任務隊列中,等待執(zhí)行。隊列就是一個先進先出的列表,先被放到隊列的回調(diào),會被優(yōu)先執(zhí)行。前面的代碼中,一共有 5 個回調(diào)函數(shù)。

回調(diào)1 是 Promise 實例化時的回調(diào),所以會立即執(zhí)行,此時控制臺打印出數(shù)字 1,然后 resolve() 方法被調(diào)用,此時的 Promise 狀態(tài)被修改成了 fulfilled(如果沒有調(diào)用 resolve() 方法,Promise 的狀態(tài)為 pending)。

Promise 實例化完成后,第一個 then() 方法被調(diào)用, 回調(diào)2 會被放入了微任務隊列中,等待執(zhí)行。

then 方法何時調(diào)用?

這個時候疑問點來了,第一個 then() 方法被調(diào)用后,第二個 then 方法會不會馬上被調(diào)用,如果會,那輸出的結(jié)果就應該是 :1,2,3,4。顯然,此時不會馬上調(diào)用第二個 then() 方法,也就是不會馬上將 回調(diào)5 放入微任務隊列。那如果不會,那何時才會被調(diào)用?

這個時候,需要看一下 Promise/A+ 規(guī)范。重點是下面幾條:

2.2 then 方法promise 的 then 方法接受兩個參數(shù):

promise.then(onFulfilled, onRejected)

2.2.2 如果 onFulfilled 是函數(shù):

  • 2.2.2.1 當 promise 處于已處理狀態(tài)時,該函數(shù)必須被調(diào)用并將 promise 的值作為第一個參數(shù)。
  • 2.2.2.2 該函數(shù)一定不能在 promise 處于已處理狀態(tài)之前調(diào)用。
  • 2.2.2.3 該函數(shù)被調(diào)用次數(shù)不超過一次。

2.2.6 then 可以在同一個 promise 上多次調(diào)用。

  • 2.2.6.1 如果 promise 處于已處理狀態(tài)時,所有相應的 onFulfilled 回調(diào)必須按照它們對 then 的組織順序依次調(diào)用。
  • 2.2.6.2 如果 promise 處于已拒絕狀態(tài)時,所有相應的 onRejected 回調(diào)必須按照它們對 then 的組織順序依次調(diào)用。

2.2.7 then 必須返回一個 promise。

promise1 = new Promise(resolve => resolve())

// promise1 可以多次調(diào)用 then
// 且 onFulfilled 回調(diào)的執(zhí)行順序,按照 .then 的調(diào)用順序執(zhí)行
promise1.then(onFulfilled1) // 1
promise1.then(onFulfilled2) // 2
promise1.then(onFulfilled3) // 3
// 上面 3 個 onFulfilled,按照 1、2、3 的順序執(zhí)行
// 調(diào)用 .then 方法后,返回一個新的 promisepromise2 = promise1.then(onFulfilled, 
onRejected);

綜上,第一個 then() 方法調(diào)用后,會返回一個新的 Promise。這樣做的目的就是為了保持鏈式調(diào)用,而且 then() 方法內(nèi)的 onFulfilled 回調(diào)會等待 Promise 狀態(tài)修改之后才會調(diào)用。

我們稍微修改一下前面代碼的調(diào)用形式,如下:

const p1 = new Promise((resolve) => {
console.log(1)
resolve()
})

const p2 = p1.then(() => {
new Promise((resolve) => {
console.log(2)
resolve()
}).then(() => {
console.log(4)
})
})

const p3 = p2.then(() => {
console.log(3)
})

p1.then() 會返回一個新的 Promise 命名為 p2,后面的 p2.then() 的回調(diào)會在 p1.then() 內(nèi)的回調(diào)函數(shù)執(zhí)行完之后,才會調(diào)用,也就是 p2 這個 Promise 狀態(tài)發(fā)生改變之后。

所以,只有 回調(diào)2 執(zhí)行完成后,才會執(zhí)行 p2.then()。我們再看 回調(diào)2 的內(nèi)容。

回調(diào)2 先是對一個 Promise 進行了實例化操作,實例化的回調(diào)為 回調(diào)3 ,該回調(diào)會立即執(zhí)行,此時控制臺打印出數(shù)字 2,然后 resolve() 方法被調(diào)用,此時的 Promise 狀態(tài)被修改成了 fulfilled,后面的 回調(diào)4 會放入微任務隊列。回調(diào)2 執(zhí)行完畢后,執(zhí)行 p2.then(),回調(diào)5 被放入微任務隊列。

按照隊列先進先出的執(zhí)行順序,先執(zhí)行 回調(diào)4,然后執(zhí)行 回調(diào)5。所以,在控制臺會先輸出數(shù)字 4,然后輸出數(shù)字 3。

如果想要輸出的結(jié)果為:1,2,3,4,可以將代碼改成如下形式:

const p1 = new Promise((resolve) => {
console.log(1)
resolve()
})

p1.then(() => {
new Promise((resolve) => {
console.log(2)
resolve()
}).then(() => {
console.log(4)
})
})

p1.then(() => {
console.log(3)
})

根據(jù)前面的 2.2.6 規(guī)則,then 可以在同一個 promise 上多次調(diào)用,且 p1 后面的 then 會按照他們的調(diào)用順序直接放入微任務隊列中。

責任編輯:姜華 來源: 自然醒的筆記本
相關推薦

2018-03-13 16:04:45

Promise執(zhí)行順序

2024-10-11 17:13:14

SQL數(shù)據(jù)庫查詢數(shù)據(jù)庫

2012-05-16 13:45:24

Java構(gòu)造器

2025-02-07 15:01:49

Promise數(shù)組前端

2024-01-02 16:16:34

Promise前端

2024-03-06 13:56:00

項目awaitpromise

2019-11-06 09:30:35

SQL查詢語句數(shù)據(jù)庫

2010-04-16 09:27:18

Ocacle執(zhí)行計劃

2021-07-28 07:22:40

SQL順序Hive

2009-07-03 16:33:13

Tapestry函數(shù)執(zhí)

2022-10-11 23:50:43

JavaScript編程Promise

2009-11-10 16:00:05

Oracle執(zhí)行計劃

2010-09-03 14:47:50

SQLSELECT語句

2010-08-27 13:07:00

CSS規(guī)則

2021-09-26 09:59:14

MYSQL開發(fā)數(shù)據(jù)庫

2022-05-10 08:47:00

JMeter作用域執(zhí)行順序

2020-07-29 17:35:08

Promise源碼前端

2023-09-15 15:31:23

異步編程Promise

2022-09-02 08:19:37

spring配置加載

2022-02-16 13:46:40

Spring Aop代碼注解
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 五月香婷婷 | 国产精品久久久久aaaa樱花 | 91精品国产综合久久香蕉922 | 国产线视频精品免费观看视频 | 亚洲aⅴ | 国产成人免费一区二区60岁 | 欧美久久久久久 | 男人视频网站 | 国产aⅴ精品 | 自拍偷拍第1页 | 中文字幕在线看第二 | 午夜小视频在线播放 | 亚洲欧美日韩网站 | 久久国产精99精产国高潮 | 日韩电影一区二区三区 | 精品久久久久久久久久久久久久久久久 | 精品久久久久久久 | 国产高清在线精品 | 久久1区| 国产精品中文字幕在线播放 | 精品一区二区三区四区五区 | 久久99网| 日韩欧美在线观看视频 | 欧美中文字幕在线观看 | 久久精品国产一区二区三区 | 免费激情网站 | 国产99久久精品 | 日韩欧美一区二区三区在线播放 | 91一区二区| 国产精品色 | 亚洲精品一区二区网址 | a黄视频| 亚洲精品综合 | 国产精品区一区二区三 | 91久久精品一区二区二区 | 国产一级在线 | www国产亚洲精品 | 日韩高清一区二区 | 国产激情精品一区二区三区 | 欧美一区日韩一区 | 激情 一区 |