首页 > 编程 > JavaScript > 正文

详解如何构建Promise队列实现异步函数顺序执行

2019-11-19 12:38:57
字体:
来源:转载
供稿:网友

场景

有a、b、c三个异步任务,要求必须先执行a,再执行b,最后执行c

且下一次任务必须要拿到上一次任务执行的结果,才能做操作

思路

我们需要实现一个队列,将这些异步函数添加进队列并且管理它们的执行,队列具有First In First Out的特性,也就是先添加进去的会被先执行,接着才会执行下一个(注意跟栈作区别)

大家也可以类比一下jQuery的animate方法,添加多个动画也会按顺序执行

解决

模拟3个异步函数

// 异步函数avar a = function () { return new Promise(function (resolve, reject) {  setTimeout(function () {   resolve('a')  }, 1000) })}// 异步函数bvar b = function (data) { return new Promise(function (resolve, reject) {  resolve(data + 'b') })}// 异步函数cvar 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对象,都可以使用

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表