<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Promise.allSettled 的作用,如何自己實現(xiàn)一個 Promise.allSettled

          共 6964字,需瀏覽 14分鐘

           ·

          2021-10-02 06:04


          點擊上方 三分鐘學前端,關注公眾號

          回復交流,加入前端編程面試算法每日一題群


          面試官也在看的前端面試資料

          引言

          本文從四個方面循序漸進介紹 Promise.allSettled

          • Promise.all() 的缺陷
          • 引入 Promise.allSettled()
          • Promise.allSettled()Promise.all() 各自的適用場景
          • 手寫 Promise.allSettled() 實現(xiàn)

          下面正文開始??

          Promise.all() 的缺陷

          我們在之前的一篇文章中 面試官問:Promise.all 使用、原理實現(xiàn)及錯誤處理 已經(jīng)介紹過,當我們使用 Promise.all() 執(zhí)行過個 promise 時,只要其中任何一個promise 失敗都會執(zhí)行 reject ,并且 reject 的是第一個拋出的錯誤信息,只有所有的 promise 都 resolve 時才會調(diào)用 .then 中的成功回調(diào)

          const p1 = Promise.resolve(1)
          const p2 = Promise.resolve(2)
          const p3 = new Promise((resolve, reject) => {
            setTimeout(reject, 1000'three');
          });

          Promise.all([p1, p2, p3])
          .then(values => {
              console.log('resolve: ', values)
          }).catch(err => {
              console.log('reject: ', err)
          }) 

          // reject:  three

          注意:其中任意一個 promiserejectPromise.all 就會立即被 reject ,數(shù)組中其它未執(zhí)行完的 promise 依然是在執(zhí)行的, Promise.all 沒有采取任何措施來取消它們的執(zhí)行

          但大多數(shù)場景中,我們期望傳入的這組 promise 無論執(zhí)行失敗或成功,都能獲取每個 promise 的執(zhí)行結(jié)果,為此,ES2020 引入了 Promise.allSettled()

          Promise.allSettled()

          Promise.allSettled() 可以獲取數(shù)組中每個 promise 的結(jié)果,無論成功或失敗

          const p1 = Promise.resolve(1)
          const p2 = Promise.resolve(2)
          const p3 = new Promise((resolve, reject) => {
            setTimeout(reject, 1000'three');
          });

          Promise.allSettled([p1, p2, p3])
          .then(values => {
              console.log(values)
          }) 

          /*
          [
            {status: "fulfilled", value: 1}, 
            {status: "fulfilled", value: 2}, 
            {status: "rejected", reason: "three"}
          ]
          */

          當瀏覽器不支持 Promise.allSettled ,可以如此 polyfill:

          if (!Promise.allSettled) {
            const rejectHandler = reason => ({status"rejected", reason})
            const resolveHandler = value => ({status"fulfilled", value})
            Promise.allSettled = promises =>
              Promise.all(
                promises.map((promise) =>
                  Promise.resolve(promise) 
                    .then(resolveHandler, rejectHandler)
                )
                // 每個 promise 需要用 Promise.resolve 包裹下
                // 以防傳遞非 promise
              );
          }

          // 使用
          const p1 = Promise.resolve(1)
          const p2 = Promise.resolve(2)
          const p3 = new Promise((resolve, reject) => {
            setTimeout(reject, 1000'three');
          })
          const promises = [p1, p2, p3]
          Promise.allSettled(promises).then(console.log)

          Promise.allSettled() 與 Promise.all() 各自的適用場景

          Promise.allSettled() 更適合:

          • 彼此不依賴,其中任何一個被 reject ,對其它都沒有影響
          • 期望知道每個 promise 的執(zhí)行結(jié)果

          Promise.all() 更適合:

          • 彼此相互依賴,其中任何一個被 reject ,其它都失去了實際價值

          手寫 Promise.allSettled 源碼

          與 Promise.all 不同的是,當 promisereject 之后,我們不會直接  reject ,而是記錄下該 reject 的值和對應的狀態(tài) 'rejected'

          同樣地,當 promise 對象被 resolve 時我們也不僅僅局限于記錄值,同時也會記錄狀態(tài) 'fulfilled'

          當所有的 promise 對象都已執(zhí)行(解決或拒絕),我們統(tǒng)一 resolve 所有的 promise 執(zhí)行結(jié)果數(shù)組

          MyPromise.allSettled = function (promises{
              return new MyPromise((resolve, reject) => {
                promises = Array.isArray(promises) ? promises : []
                let len = promises.length
                const argslen = len
                // 如果傳入的是一個空數(shù)組,那么就直接返回一個resolved的空數(shù)組promise對象
                if (len === 0return resolve([])
                // 將傳入的參數(shù)轉(zhuǎn)化為數(shù)組,賦給args變量
                let args = Array.prototype.slice.call(promises)
                // 計算當前是否所有的 promise 執(zhí)行完成,執(zhí)行完畢則resolve
                const compute = () => {
                  if(--len === 0) { 
                    resolve(args)
                  }
                }
                function resolvePromise(index, value{
                  // 判斷傳入的是否是 promise 類型
                  if(value instanceof MyPromise) { 
                    const then = value.then
                    then.call(value, function(val{
                      args[index] = { status'fulfilled'value: val}
                      compute()
                    }, function(e{
                      args[index] = { status'rejected'reason: e }
                      compute()
                    })
                  } else {
                    args[index] = { status'fulfilled'value: value}
                    compute()
                  }
                }
             
                for(let i = 0; i < argslen; i++){
                  resolvePromise(i, args[i])
                }
              })
            }

          總結(jié)

          彼此相互依賴,一個失敗全部失效(全無或全有)用 Promise.all ;相互獨立,獲取每個結(jié)果用 Promise.allSettled

          來自:https://github.com/sisterAn/blog

          最后

          歡迎關注「三分鐘學前端」,回復「交流」自動加入前端三分鐘進階群,每日一道編程算法面試題(含解答),助力你成為更優(yōu)秀的前端開發(fā)!
          》》面試官也在看的前端面試資料《《
          “在看和轉(zhuǎn)發(fā)”就是最大的支持
          瀏覽 98
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  逼特逼在线观看 | 加勒比精品在线 | 影音先锋一区二区三区 | www.鸡巴 | 女人操逼网 |