Promise.all 的缺陷

前言

Promisees6 新出的語法,用來處理異步請求,解決以前沒有 Promise 時的回調地獄。Promise 有幾個api, Promise.resolve,Promise.reject,Promise.all,Promise.race。關於多個異步的處理咱們能夠用 Promise.all,但 Promise.all 只在全部的 promiseresolve 時纔會調用 .then 中的成功回調。 有時候多個請求不免會有失敗的狀況,咱們想當 Promise.all中的 promise 對象 reject 失敗時也可以調用回調函數,這個時候應該怎麼作呢?es6

開搞

咱們先來了解下 Promise.all 的用法。api

Promise.all([Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)])
.then(res => console.log(res),err=>console.log(err))
// [1, 2, 3]

 Promise.all([Promise.reject(1), Promise.resolve(2), Promise.resolve(3)])
.then(res => console.log(res),err=>console.log(err))
// 1
複製代碼

Promise.all 中傳入的是多個 promise 對象組成的數組。數組中全部的 promise 成功時纔會打印 res ,只要有一個失敗就會打印 err數組

咱們想要達到就算失敗也能打印全部的信息,應該怎麼作呢?很簡單,用.then 由於.then返回的也是一個 promise 對象,無論是resolve仍是reject都會執行.then。返回promise對象後就變成resovle狀態了。promise

Promise.all([Promise.reject(1).then((res) => ({ status: 'ok', res }), (err) => ({ status: 'not ok', err })), 
Promise.resolve(2).then((res) => ({ status: 'ok', res }), (err) => ({ status: 'not ok', err })), 
Promise.resolve(3).then((res) => ({ status: 'ok', res }), (err) => ({ status: 'not ok', err }))])
.then(res => console.log(res),err=>console.log(err))
//[ {status: "not ok", err: 1},{status: "ok", res: 2},{status: "ok", res: 3}]
複製代碼

這樣就打印出了全部的信息,即使Promise.all中有reject狀態。異步

優化封裝

如今這種寫法很繁瑣,每一個數組中的每一個promise都要寫一樣的.then。咱們能夠把.then抽離出來。封裝成一個函數,而後用map方法,對每一個promise .then一下,而後返回新的數組。函數

function handlePromise(promiseList) {
    return promiseList.map(promise =>
      promise.then((res) => ({ status: 'ok', res }), (err) => ({ status: 'not ok', err }))
    )
  }
複製代碼

這樣調用promise.all時,能夠這麼寫:優化

Promise.all(handlePromise([Promise.reject(1),Promise.resolve(2),Promise.resolve(3)]))
.then(res => console.log(res),err=>console.log(err))
複製代碼

也是一樣的效果。ui

甚至咱們能夠寫一個Promise.allSettled方法:spa

Promise.allSettled2 = function (promiseList) {
    return Promise.all(handlePromise(promiseList))
  }
Promise.allSettled2 ([Promise.reject(1),Promise.resolve(2),Promise.resolve(3)]).then(res => console.log(res), err => console.log(err))
複製代碼

這就是promise新出的allSettled Api`,只不過兼容性不太好,不過沒事,看了這篇文章以後,咱們能夠本身封裝個同樣功能的api了。完結撒花。 code

image.png
相關文章
相關標籤/搜索