串行執行promise


Promise提供了Promise.all,Promise.race,Promise.allSettled等多個Promise對象間的運行關系,如果並行運行可以用Promise.all來進行處理,如果要串行運行可以用數組的reduce來進行處理,處理代碼如下:

    const serialPromises = function (promises) {
      promises.reduce((prev, next) => prev.then((preVal) => next(preVal)), Promise.resolve());
    }

  測試代碼

    const fn1 = function (args) {
      console.log('fn1',args)
      return Promise.resolve('111')
    }
    const fn2 = function (args) {
      console.log('fn2',args)
      return Promise.resolve('222')
    }
    const fn3 = function (args) {
      console.log('fn3',args)
      return Promise.resolve('333')
    }
    serialPromises([fn1, fn2, fn3])

  測試結果:

fn1 undefined
fn2 111
fn3 222

上面serialPromises有個問題如果有個fn2執行reject那么執行鏈會發生中斷

測試代碼

    const fn1 = function (args) {
      console.log('fn1',args)
      return Promise.resolve('111')
    }
    const fn2 = function (args) {
      console.log('fn2',args)
      return Promise.reject('222')
    }
    const fn3 = function (args) {
      console.log('fn3',args)
      return Promise.resolve('333')
    }
    serialPromises([fn1, fn2, fn3])

測試結果

fn1 undefined
fn2 111
Uncaught (in promise) 222

改進一下

    const serialPromises2 = function (promises) {
      promises.reduce((prev, next) => prev.then(next).catch(next), Promise.resolve());
    }

 

測試代碼

    const fn1 = function (args) {
      console.log('fn1',args)
      return Promise.resolve('111')
    }
    const fn2 = function (args) {
      console.log('fn2',args)
      return Promise.reject('222')
    }
    const fn3 = function (args) {
      console.log('fn3',args)
      return Promise.resolve('333')
    }
    serialPromises2([fn1, fn2, fn3])

  測試結果

fn1 undefined
fn2 111
fn2 222
fn3 222

  

這個方法也有個問題是如果有fn2執行reject,那么那個fn2會執行兩次,這是因為p.catch等價於p.then(undefined, onRejected)

我們再次改進

    const serialPromises3=function(promises){
      const process=function(i,args){
        const curr=promises[i]
        const next=function(res){process(i+1,res)}
        if(curr)curr(args).then(next).catch(next)
      }
      process(0)
    }

 

測試代碼

    const fn1 = function (args) {
      console.log('fn1',args)
      return Promise.resolve('111')
    }
    const fn2 = function (args) {
      console.log('fn2',args)
      return Promise.reject('222')
    }
    const fn3 = function (args) {
      console.log('fn3',args)
      return Promise.resolve('333')
    }
    serialPromises3([fn1, fn2, fn3])

  測試結果

fn1 undefined
fn2 111
fn3 222

  

至此問題終於解決了!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM