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

原文:https://blog.csdn.net/u011500781/article/details/73883903

场景
有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队列实现异步函数顺序执行)