美文网首页vuejavascript
构建Promise队列实现异步函数顺序执行

构建Promise队列实现异步函数顺序执行

作者: 小小的开发人员 | 来源:发表于2019-04-01 21:25 被阅读46次

    场景

    • 有a、b、c三个异步任务,要求必须先执行a,再执行b,最后执行c
    • 且下一次任务必须要拿到上一次任务执行的结果,才能做操作

    思路

    • 我们需要实现一个队列,将这些异步函数添加进队列并且管理它们的执行,队列具有First In First Out的特性,也就是先添加进去的会被先执行,接着才会执行下一个(注意跟栈作区别)
    • 大家也可以类比一下jQuery的animate方法,添加多个动画也会按顺序执行

    解决

    • 模拟3个异步函数

      // 异步函数a
      var a = function () {
        return new Promise(function (resolve, reject) {
          setTimeout(function () {
            resolve('a')
          }, 1000)
        })
      }
      
      // 异步函数b
      var b = function (data) {
        return new Promise(function (resolve, reject) {
          resolve(data + 'b')
        })
      }
      
      // 异步函数c
      var c = function (data) {
        return new Promise(function (resolve, reject) {
          setTimeout(function () {
            resolve(data + 'c')
          }, 500)
        })
      }
      
    • 解决方法一(使用then链式操作)

      • 特点:可以满足需求,但是书写比较繁琐

      • 代码

        //链式调用
        a()
          .then(function (data) {
            return b(data)
          })
          .then(function (data) {
            return c(data)
          })
          .then(function (data) {
            console.log(data)// abc
          })
        
    • 方法二(构建队列)

      • 特点:封装方法,可移植到别处使用

      • 代码

        // 构建队列
        function queue(arr) {
          var sequence = Promise.resolve()
          arr.forEach(function (item) {
            sequence = sequence.then(item)
          })
          return sequence
        }
        
        // 执行队列
        queue([a, b, c])
          .then(data => {
            console.log(data)// abc
          })
        
    • 方法三(使用async、await构建队列)

      • 同方法二,只是显得更高大上点

      • 代码

        async function queue(arr) {
          let res = null
          for (let promise of arr) {
            res = await promise(res)
          }
          return await res
        }
        queue([a, b, c])
          .then(data => {
            console.log(data)// abc
          })
        
    • 顺便说一句,bluebird的Promise.reduce也可以用来顺序执行函数,但是可使用的场景非常有限,一般用来读取文件信息,而以上给出的方法,不管你在异步函数中做了什么,只要函数最后返回了一个Promise对象,都可以使用。

    相关文章

      网友评论

        本文标题:构建Promise队列实现异步函数顺序执行

        本文链接:https://www.haomeiwen.com/subject/ignbbqtx.html