Promise的深度理解(二)
阿新 • • 發佈:2021-02-14
好久不見,甚是想念
今天你敲程式碼了嘛!?讓我們接著來看看Promise會遇到的一些問題吧
如果沒有看(一)的要先去看去哦
友情連結https://blog.csdn.net/weixin_49449198/article/details/113524157
如果看完了,讓我們接著說吧
三、改變 promise 狀態和指定回撥函式誰先誰後
-
都有可能,正常情況下是先指定回撥再改變狀態,但也可以改狀態再指定回撥
-
如何先改狀態再指定回撥
- 在執行器中直接呼叫 resolve()/ reject()
- 延遲更長時間才呼叫 then()
// 常規 : 先指定回撥函式,後改變的狀態
new Promise((resolve, reject)=>{
setTimeout(()=>{
reject(3);
console.log(2);
// resolve(1); // 後改變的狀態(同時指定資料) 非同步執行回撥函式
},1000)
})
.then(value=>{ // 先指定回撥,儲存當前指定的回撥函式
// console.log(value);
},reason=>{
console.log(reason);
})
// 2
// 3
// 如何先改狀態 ,後指定回撥函式
new Promise((resolve,reject) =>{
resolve('a'); // 先改變的狀態
reject('b');
})
.then(value=>{ // 後指定回撥,非同步執行回撥函式
console.log(value);
},reason=>{
console.log(reason);
})
//a
四、Promise.then() 返回的新 promise 的結果狀態由什麼決定
- 簡單表達 : 由 then() 指定的回撥函式執行的結果決定
- 詳細表達 :
- 如果丟擲異常,新 promise 變為 rejected,reason 為丟擲異常結果
- 如果返回的時非 promise 的任意值,新promise 變為 resolved value為返回的值
- 如果返回的是另一個新 promise 此 promise的結果就會成為新promise的結果
const p = new Promise((resolve,reject)=>{
// resolve(1)
reject(1)
}).then(
value => {
console.log('onResolve1()',value);
},
reason => {
console.log('onReject()1',reason);
}
).then(
value => {
console.log('onResolve2()',value);
},
reason => {
console.log('onReject()2',reason);
}
)
讓我們看一下輸出結果
我們來分析一下 因為改變了狀態 reject 所以進入了 reason(失敗)的回撥函式
但是下一次回撥的狀態沒有給,所以預設 成功 return undefined
因此為了避免造成這種問題
也就證明了以下這句話
如果返回的是非 promise 的任意值,新promise 變為 resolved
value為返回的值
五、Promise 如何串聯多個操作任務
- promise 的 then()返回一個新的promise,可以開成then() 的鏈式呼叫
- 通過then的鏈式呼叫串聯多個同步/非同步操作
const p = new Promise((resolve,reject)=>{
resolve(1)
}).then(
value => {
console.log('onResolve1()',value);
resolve(2)
}
).then(
value => {
console.log('onResolve2()',value);
})
這說明then以後 是不能直接使用 resolve的,因為resolve是最外層的Promise的,我們要是想繼續串聯下面的任務
成功
(1)return Promise.resolve()
(2)直接return 想要的東西
(3)return new Promise((resolve,reject)=>{
resolve()
})
失敗
(1)return Promise.reject()
(2)throw 直接拋錯
(3)return new Promise(()=>{
reject()
})
舉個栗子:
new Promise((resolve,reject)=>{
setTimeout(()=>{
console.log('執行非同步任務1');
resolve(1);
},1000)
}).then(
value=>{
console.log('執行同步任務2');
return 2;
}
).then(
value => {
console.log('任務2的結果',value);
return new Promise((resolve,reject)=>{
// 啟動任務3 非同步
setTimeout(()=>{
console.log('執行任務 3 非同步');
resolve(3);
},1000)
})
}
).then(
value => {
console.log('任務3的結果',value);
}
)
六、Promise 異常傳透
- 當使用promise 的then鏈式呼叫時,可以在最後指定失敗的回撥
- 前面任何操作處理異常,都會傳到最後失敗的回撥中處理
new Promise((resolve,reject)=>{
reject(1)
}).then(
value=>console.log(value)
).then(
value=>console.log(value)
).then(
value=>console.log(value)
).catch(
reason=>console.log(reason)
)
//1
先看一下輸出結果
造成這種問題是 如果Promise 丟擲 reject狀態,但是then裡面沒有 reason(失敗)的回撥來接住,就會預設 reason=>{throw reason} 就會繼續向下傳遞,直到catch接住
七、中斷promise鏈
- 當使用 promise的then 鏈式呼叫時,在中間中斷,不再呼叫後面的回撥函式
- 辦法 : 在回撥函式中返回一個 pendding 狀態的promise物件
const p = new Promise((resolve,reject)=>{
resolve(1)
})
p.then(value=>{
console.log(value)
//throw 2
return new Promise(()=>{})
}).catch(reason=>{
console.log(reason)}
)
返回一個 pendding 狀態的promise物件 就可以中斷Promise鏈了