<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>

          今日一題 - 請模擬實(shí)現(xiàn)一個(gè)Promise.all() 方法?

          共 5122字,需瀏覽 11分鐘

           ·

          2021-01-24 11:09

          對Promise.all 的理解

          Promise.all()方法用于將多個(gè) Promise 實(shí)例,包裝成一個(gè)新的 Promise 實(shí)例。

          Promise.all()方法的參數(shù)可以不是數(shù)組,但必須具有 Iterator 接口(所以數(shù)組、Map、Set都可以),并且只返回一個(gè)Promise實(shí)例,輸入的所有promise的resolve回調(diào)的結(jié)果會(huì)按傳入的按順序作為一個(gè)數(shù)組的其中一項(xiàng)返回。

          當(dāng)然也支持非promise對象的傳入,會(huì)作為數(shù)組中的一項(xiàng)返回。

          返回結(jié)果的兩個(gè)特點(diǎn)

          全部成功一起返回:當(dāng)接收的所有Promise實(shí)例都執(zhí)行成功后才會(huì)返回結(jié)果,返回的結(jié)果是一個(gè)數(shù)組,返回值將會(huì)按照參數(shù)內(nèi)的 promise 順序排列,而不是由調(diào)用 promise 的完成順序決定。

          失敗快速返回:當(dāng)其中一個(gè)Promise實(shí)例執(zhí)行失敗了就會(huì)立刻返回,只返回失敗的結(jié)果,不會(huì)管其他promise執(zhí)行的結(jié)果。

          使用方式 - promise 實(shí)例全部成功一起返回

          let?p1?=?new?Promise((resolve,?reject)?=>?{
          ??resolve('p1')
          })
          let?p2?=?new?Promise((resolve,?reject)?=>?{
          ??resolve('p2')
          })

          let?p3?=?new?Promise((resolve,?reject)?=>?{
          ??resolve('p3')
          })


          //全部成功的情況,接收p1?p2,?p3
          Promise.all([p1,?p2,?p3]).then(results?=>?{
          ??console.log(results)
          }).catch(error?=>?{
          ??console.log(error)
          })

          使用方式 - 失敗快速返回

          即便是最后一個(gè)promise 失敗了,也會(huì)提前返回,不會(huì)等待前面的promise返回.

          var?p1?=?new?Promise((resolve,?reject)?=>?{
          ??setTimeout(resolve,?1000,?'one');
          });
          var?p2?=?new?Promise((resolve,?reject)?=>?{
          ??setTimeout(resolve,?2000,?'two');
          });
          var?p3?=?new?Promise((resolve,?reject)?=>?{
          ??setTimeout(resolve,?3000,?'three');
          });
          var?p4?=?new?Promise((resolve,?reject)?=>?{
          ??setTimeout(resolve,?4000,?'four');
          });
          var?p5?=?new?Promise((resolve,?reject)?=>?{
          ??reject('reject');
          });

          Promise.all([p1,?p2,?p3,?p4,?p5]).then(values?=>?{
          ??console.log(values);
          },?reason?=>?{
          ??console.log(reason)
          });

          如果傳入的是非promise對象呢?

          如果參數(shù)中包含非 promise 值,這些值將被忽略,但仍然會(huì)被放在返回?cái)?shù)組中.

          var?p?=?Promise.all([1,2,3]);
          var?p2?=?Promise.all([1,2,3,?Promise.resolve(4)]);
          var?p3?=?Promise.all([1,2,3,?Promise.reject(5)]);
          setTimeout(function(){
          ????p.then(res=>console.log(res))
          ?????p2.then(res=>console.log(res))
          ?????p3.then(res=>console.log(res))
          });

          錯(cuò)誤處理

          因?yàn)镻roims.all() 結(jié)果返回的是一個(gè) promise對象,所以和普通的promise錯(cuò)誤處理是一樣的。

          可以通過reject或者catch來進(jìn)行捕獲。

          ?//1?catch
          ?//....
          ?Promise.all([p1,?p2,p3]).then(results?=>?{
          ????console.log(results)????//?['p1',?'p2']
          ??}).catch(error?=>?{
          ????//錯(cuò)誤捕獲
          ????console.log(error)
          ??})
          ??
          ?//2?reject
          ?//....
          ?Promise.all([p1,?p2,p3]).then(results?=>?{
          ????console.log(results)????//?['p1',?'p2']
          ??},(error){
          ?//錯(cuò)誤捕獲
          ??console.log(error)
          })

          模擬實(shí)現(xiàn)

          上面的幾個(gè)特點(diǎn)就是我們思考的入口,也是必須要滿足的條件。

          • 多個(gè)promise最后返回一個(gè)promise
          • 必須全部成功才會(huì)返回
          • 失敗會(huì)優(yōu)先返回,不會(huì)等他promise結(jié)果
          ?function?customerPromiseAll(promises)?{
          ????return?new?Promise((resolve,?reject)?=>?{
          ??????let?resultCount?=?0;?//計(jì)數(shù)器
          ??????let?promiseLen?=?promises.length;?//傳入的promise個(gè)數(shù)
          ??????let?results?=?new?Array(promiseLen);//初始化數(shù)組用于存放返回結(jié)果
          ?
          ??????//按順序執(zhí)行
          ??????for?(let?i?=?0;?i?????????promises[i].then(value?=>?{
          ??????????resultCount++;
          ??????????results[i]?=?value;?//保證執(zhí)行結(jié)果的順序
          ??????????if?(resultCount?===?promises.length)?{
          ????????????return?resolve(results)?//執(zhí)行完最后一個(gè)promise,則返回
          ??????????}
          ????????},?error?=>?{
          ??????????reject(error)?//執(zhí)行錯(cuò)誤直接reject
          ????????})
          ??????}
          ????})
          ??}

          驗(yàn)證一下

          ??let?p1?=?new?Promise(resolve?=>?resolve('p1'))
          ??let?p2?=?new?Promise(resolve?=>?resolve('p2'))
          ??let?p3?=?Promise.reject('p3?error')

          ??customerPromiseAll([p1,?p2]).then(results?=>?{
          ????console.log(results)????//?['p1',?'p2']
          ??}).catch(error?=>?{
          ????console.log(error)
          ??})

          ??customerPromiseAll([p1,?p2,?p3]).then(results?=>?{
          ????console.log(results)
          ??}).catch(error?=>?{
          ????console.log(error)??????//?'p3?error'
          ??})

          驗(yàn)證通過,結(jié)果沒啥毛病,符合預(yù)期。

          支持非promise對象

          上面我們驗(yàn)證傳入都是常規(guī)的promise對象,如果傳入非promise對象呢?

          customerPromiseAll([1,2,3])?//emmm?.直接報(bào)錯(cuò)了

          所以我們需要增加驗(yàn)證傳入的值是不是promise,非promise對象,則直接resolve。

          //驗(yàn)證是否是promise對象
          function?isPromise(obj)?{
          ??return?!!obj??//有實(shí)際含義的變量才執(zhí)行方法,變量null,undefined和''空串都為false
          ???&&?(typeof?obj?===?'object'?||?typeof?obj?===?'function')?//?初始promise?或?promise.then返回的
          ???&&?typeof?obj.then?===?'function';
          }

          完整代碼 1 非promise 對下直接存入數(shù)組

          function?customerPromiseAll(promises)?{
          ????return?new?Promise((resolve,reject)=>{
          ????????let?resultCount?=?0;
          ????????//計(jì)數(shù)器
          ????????let?promiseLen?=?promises.length;
          ????????//傳入的promise個(gè)數(shù)
          ????????let?results?=?new?Array(promiseLen);
          ????????//初始化數(shù)組用于存放返回結(jié)果

          ????????//按順序執(zhí)行
          ????????for?(let?i?=?0;?i?????????????if?(!isPromise(promises[i]))?{
          ????????????????resultCount++;
          ????????????????results[i]?=?promises[i];?//直接存儲(chǔ)結(jié)果

          ????????????????if?(resultCount?===?promiseLen)?{
          ????????????????????return?resolve(results)
          ????????????????????//執(zhí)行完最后一個(gè)promise,則返回
          ????????????????}
          ????????????}?else?{
          ????????????????promises[i].then(value=>{
          ????????????????????resultCount++;
          ????????????????????results[i]?=?value;?//存儲(chǔ)resolve的結(jié)果
          ????????????????????//保證執(zhí)行結(jié)果的順序
          ????????????????????if?(resultCount?===?promiseLen)?{
          ????????????????????????return?resolve(results)
          ????????????????????????//執(zhí)行完最后一個(gè)promise,則返回
          ????????????????????}
          ????????????????}
          ????????????????,?error=>{
          ????????????????????reject(error)
          ????????????????????//執(zhí)行錯(cuò)誤直接reject
          ????????????????}
          ???????????????)

          ????????????}
          ????????}
          ????}
          ???)
          }

          完整代碼2 非promise對象調(diào)用Promise.resolve()返回一個(gè)promise對象

          function?customerPromiseAll(promises)?{
          ????return?new?Promise((resolve,reject)=>{
          ????????let?resultCount?=?0;
          ????????//計(jì)數(shù)器
          ????????let?promiseLen?=?promises.length;
          ????????//傳入的promise個(gè)數(shù)
          ????????let?results?=?new?Array(promiseLen);
          ????????//初始化數(shù)組用于存放返回結(jié)果

          ????????//按順序執(zhí)行
          ????????for?(let?i?=?0;?i?????????????let?curPromise?=?promises[i]
          ????????????if?(!isPromise(curPromise))?{
          ????????????????curPromise?=?Promise.resolve(curPromise)
          ????????????}
          ????????????curPromise.then(value=>{
          ????????????????resultCount++;
          ????????????????results[i]?=?value;
          ????????????????//存儲(chǔ)resolve的結(jié)果
          ????????????????//保證執(zhí)行結(jié)果的順序
          ????????????????if?(resultCount?===?promiseLen)?{
          ????????????????????return?resolve(results)
          ????????????????????//執(zhí)行完最后一個(gè)promise,則返回
          ????????????????}
          ????????????}
          ????????????,?error=>{
          ????????????????reject(error)
          ????????????????//執(zhí)行錯(cuò)誤直接reject
          ????????????}
          ???????????)

          ????????}
          ????}
          ???)
          }

          最后

          平時(shí)對Promise.all方法只是處于使用的層面,其實(shí)深挖一下的話收獲還是很多的。

          今天就到這里,希望對你有用。

          點(diǎn)個(gè)『在看』支持下?

          瀏覽 60
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <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>
                  妻av毛片 | 大香蕉视频在线精品 | 很很操在线观看 | 91精品久久电影 | 夜夜夜撸|