详解如何构建Promise队列实现异步函数顺序执行
Posted xanthedsf
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了详解如何构建Promise队列实现异步函数顺序执行相关的知识,希望对你有一定的参考价值。
场景
有a、b、c三个异步任务,要求必须先执行a,再执行b,最后执行c
且下一次任务必须要拿到上一次任务执行的结果,才能做操作
思路
我们需要实现一个队列,将这些异步函数添加进队列并且管理它们的执行,队列具有First In First Out的特性,也就是先添加进去的会被先执行,接着才会执行下一个(注意跟栈作区别)
大家也可以类比一下jQuery的animate方法,添加多个动画也会按顺序执行
解决
模拟3个异步函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
// 异步函数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链式操作)
特点:可以满足需求,但是书写比较繁琐
代码
1
2
3
4
5
6
7
8
9
10
11
|
//链式调用 a() .then( function (data) { return b(data) }) .then( function (data) { return c(data) }) .then( function (data) { console.log(data) // abc }) |
方法二(构建队列)
特点:封装方法,可移植到别处使用
代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
// 构建队列 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构建队列)
同方法二,只是显得更高大上点
代码
1
2
3
4
5
6
7
8
9
10
11
|
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队列实现异步函数顺序执行的主要内容,如果未能解决你的问题,请参考以下文章
同步和异步 setTimeou(异步) async和await promise(疑惑点)