急需收集看到的Promise練習(xí)題,方便各位練習(xí),上兩期可看
Promise練習(xí)題 II
Promise練習(xí)題 I
問(wèn)下面代碼的輸出順序
const first = () => (new Promise((resolve, reject) => {
console.log(3);
let p = new Promise((resolve, reject) => {
console.log(7);
setTimeout(() => {
console.log(5);
resolve(6);
}, 0)
resolve(1);
});
resolve(2);
p.then((arg) => {
console.log(arg);
});
}));
first().then((arg) => {
console.log(arg);
});
console.log(4);
上面這個(gè)代碼結(jié)合了同步異步的輸出,兩個(gè)Promise包裹,以及Promise的狀態(tài)只會(huì)改變一次的知識(shí)點(diǎn)
首先從同步輸出開(kāi)始
- first首先被調(diào)用,此時(shí)開(kāi)始執(zhí)行
first的內(nèi)部代碼
1.1 那么首先輸出的是console.log(3)
1.2 之后first內(nèi)還包裹了一個(gè)Promise,并且也調(diào)用了then方法,那么還是會(huì)先輸出這個(gè)Promise內(nèi)部的同步代碼console.log(7)
1.3 之后是一個(gè)定時(shí)器是一個(gè)宏任務(wù),先掛起不執(zhí)行,之后是resolve(1),將內(nèi)部Promise的狀態(tài)改為成功,并且傳參1
1.4resolve(2)將外部Promise的狀態(tài)改為成功,并且傳參2
1.5 調(diào)用了內(nèi)部Promise的then方法,接受上面的傳參1,但是這里的then是屬于微任務(wù),所以不執(zhí)行
整個(gè)first內(nèi)部執(zhí)行完成 -
first().then,接收到傳參2,但是因?yàn)?code>then方法是個(gè)微任務(wù),所以也是先不執(zhí)行 -
console.log(4)是最后一個(gè)同步任務(wù)直接輸出
那么同步任務(wù)輸出順序是3 7 4
之后是上面掛起的微任務(wù)
- 內(nèi)部Promise的
then方法開(kāi)始輸出1 - 外部Promise的
then方法開(kāi)始輸出2
所以微任務(wù)輸出順序是1 2
最后是宏任務(wù)
上面只掛起了一個(gè)定時(shí)器宏任務(wù),當(dāng)微任務(wù)執(zhí)行完成之后,開(kāi)始執(zhí)行,先輸出console.log(5)
內(nèi)部還有一個(gè)resolve(6)
但是之前已經(jīng)resolve(1)了,Promise的狀態(tài)只能更改一次,所以這句不會(huì)執(zhí)行
最后宏任務(wù)輸出5
按照同步>微任務(wù)>宏任務(wù)的執(zhí)行順序,輸出3 7 4 1 2 5即為最后結(jié)果

asyncThing1()
.then(function() {
return asyncThing2();
})
.then(function() {
return asyncThing3();
})
.catch(function(err) {
return asyncRecovery1();
})
.then(
function() {
return asyncThing4();
},
function(err) {
return asyncRecovery2();
}
)
.catch(function(err) {
console.log("Don't worry about it");
})
.then(function() {
console.log("All done!");
});
這里的所有函數(shù)都理解為封裝的異步方法,題目來(lái)源于JavaScript Promises: An introduction,是一個(gè)開(kāi)放性的題目,主要針對(duì)then和catch的參數(shù),題目答案如下

已經(jīng)知道Promise有兩種情況,成功就走
then,失敗就走catch總結(jié)要點(diǎn):
catch能夠捕獲前面所有的異步異常,例如圖中的asyncThing1() asyncThing2() asyncThing3()的錯(cuò)誤都會(huì)被asyncRecovery1()捕獲catch是捕捉所有為處理的錯(cuò)誤,then只負(fù)責(zé)前面的那個(gè)Promise