1. 程式人生 > 其它 >Promise的深度理解(二)

Promise的深度理解(二)

好久不見,甚是想念
今天你敲程式碼了嘛!?讓我們接著來看看Promise會遇到的一些問題吧
如果沒有看(一)的要先去看去哦
友情連結https://blog.csdn.net/weixin_49449198/article/details/113524157
如果看完了,讓我們接著說吧

三、改變 promise 狀態和指定回撥函式誰先誰後

  1. 都有可能,正常情況下是先指定回撥再改變狀態,但也可以改狀態再指定回撥

  2. 如何先改狀態再指定回撥

    1. 在執行器中直接呼叫 resolve()/ reject()
    2. 延遲更長時間才呼叫 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 的結果狀態由什麼決定

  1. 簡單表達 : 由 then() 指定的回撥函式執行的結果決定
  2. 詳細表達 :
    1. 如果丟擲異常,新 promise 變為 rejected,reason 為丟擲異常結果
    2. 如果返回的時非 promise 的任意值,新promise 變為 resolved value為返回的值
    3. 如果返回的是另一個新 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 如何串聯多個操作任務

  1. promise 的 then()返回一個新的promise,可以開成then() 的鏈式呼叫
  2. 通過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 異常傳透

  1. 當使用promise 的then鏈式呼叫時,可以在最後指定失敗的回撥
  2. 前面任何操作處理異常,都會傳到最後失敗的回撥中處理
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鏈

  1. 當使用 promise的then 鏈式呼叫時,在中間中斷,不再呼叫後面的回撥函式
  2. 辦法 : 在回撥函式中返回一個 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鏈了