Promise鏈式調用特性總結

相信各位前端小夥伴對於Promise應該很熟悉了吧,平常工做中,100%會用到的一個東西,除非你還在用callback解決異步,那我就太佩服了。話很少說,進入正題。前端

提早聲明一下,如下代碼在node環境中實現,你能夠建立一個文件,使用nodemon這個工具執行這個文件,就能夠進行監聽更新,真香。node

首先你要建立一個promisepromise

let p=new Promise((resolve,reject)=>{
  resolve('first resolve')
})

方式1、經過return傳遞結果

p.then(res=>{
  return res;
}).then(res=>{
  console.log(res)
})

控制檯就會輸出:first resolveapp

方式2、經過返回新的promise resolve結果

p.then(res=>{
  return res;
}).then(res=>{
  return new Promise((resolve,reject)=>{
    resolve('second resolve: '+res)
  })
}).then(res=>{
  console.log(res)
})

控制檯就會輸出:second resolve: first resolve
若是在返回的promise里加一個異步好比settimeout呢,結果會是什麼樣?異步

p.then(res=>{
  return res;
}).then(res=>{
  return new Promise((resolve,reject)=>{
    // resolve('second resolve: '+res)
    setTimeout(()=>{
      resolve('second resolve: '+res)
    },2000)
  })
}).then(res=>{
  console.log(res)
})

控制檯等待2s後輸出:second resolve: first resolve函數

方式3、經過返回新的promise reject 緣由

既然能夠經過新的promise resolve,那麼reject應該也能夠。工具

p.then(res=>{
  return res;
}).then(res=>{
  return new Promise((resolve,reject)=>{
    setTimeout(()=>{
      reject('error')
    },2000)
  })
}).then(res=>{
  console.log(res)
},err=>{
  console.log('error: '+err)
})

控制檯等待2s後輸出:error: errorcode

方式4、then函數走了失敗回調繼續走then

緊接着上一步,失敗後,reject出緣由,繼續後面thenget

p.then(res=>{
  return res;
}).then(res=>{
  return new Promise((resolve,reject)=>{
    setTimeout(()=>{
      reject('error')
    },2000)
  })
}).then(res=>{
  console.log(res)
},err=>{
  console.log('error: '+err)
  // 默認 return undefined
}).then(res=>{
  console.log('second then success: '+res)
},err=>{
  console.log('second then error: '+err)
})

控制檯會輸出兩行內容:error: error,second then success: undefined。這就代表在reject 後面繼續then會執行下一步的resolve,若是上一步沒有返回值,默認接收undefined。源碼

方式5、then中使用throw new Error狀況

若是在then中拋出異常呢,如何顯示?

p.then(res=>{
  return res;
}).then(res=>{
  return new Promise((resolve,reject)=>{
    setTimeout(()=>{
      reject('error')
    },2000)
  })
}).then(res=>{
  console.log(res)
},err=>{
  console.log('error: '+err)
}).then(res=>{
  throw new Error('happend error')
}).then(res=>{
  console.log('third then success'+res)
},err=>{
  console.log('third then error '+err)
})

控制檯會輸出:
error: error
third then error Error: happend error
這代表throw error拋出異常相似reject,會由下一步的then方法中的錯誤方法處理。

方式6、在promise中使用catch進行錯誤捕獲

p.then(res=>{
  return res;
}).then(res=>{
  return new Promise((resolve,reject)=>{
    setTimeout(()=>{
      reject('error')
    },2000)
  })
}).then(res=>{
  console.log(res)
},err=>{
  console.log('error: '+err)
}).then(res=>{
  throw new Error('happend error')
}).then(res=>{
  console.log('third then success'+res)
}).catch(err=>{
  console.log('catched '+err)
})

控制檯會輸出:
error: error
catched Error: happend error

若是在catch方法的前面then中有對上一步錯誤的處理辦法會怎麼樣呢?

p.then(res=>{
  return res;
}).then(res=>{
  return new Promise((resolve,reject)=>{
    // resolve('second resolve: '+res)
    setTimeout(()=>{
      reject('error')
    },2000)
  })
}).then(res=>{
  console.log(res)
},err=>{
  console.log('error: '+err)
}).then(res=>{
  throw new Error('happend error')
}).then(res=>{
  console.log('third then success'+res)
},err=>{
  console.log('third then error '+ err)
}).catch(err=>{
  console.log('catched '+err)
})

控制檯會輸出:
error: error
third then error Error: happend error
這說明catch捕獲,若是catch前面有error處理函數,catch不會捕獲異常的。

若是在catch後面繼續then呢?

p.then(res=>{
  return res;
}).then(res=>{
  return new Promise((resolve,reject)=>{
    // resolve('second resolve: '+res)
    setTimeout(()=>{
      reject('error')
    },2000)
  })
}).then(res=>{
  console.log(res)
},err=>{
  console.log('error: '+err)
}).then(res=>{
  throw new Error('happend error')
}).then(res=>{
  console.log('third then success'+res)
}).catch(err=>{
  console.log('catched '+err)
  return 'catched error'
}).then(res=>{
  console.log('catched then '+res)
})

控制檯會輸出:
error: error
catched Error: happend error
catched then catched error
這說明catch後面是能夠繼續調用then的,catch 在promise的源碼裏面其實也是一個then,catch遵循then的運行規則。

總結

promise鏈式調用,具體是失敗仍是成功,取決於如下狀況:

成功的條件

  • then return 一個普通的js 值
  • then return 一個新的promise成功態的結果 resolve處理

失敗的條件

  • then return 一個新的promise失敗態的緣由 error
  • then throw拋出異常

以上就是promise鏈式調用的一些實踐總結,複習複習基礎知識。歡迎你們交流。

參考資料:

相關文章
相關標籤/搜索