详解如何构建Promise队列实现异步函数顺序执行
场景
有a、b、c三个异步任务,要求必须先执行a,再执行b,最后执行c
且下一次任务必须要拿到上一次任务执行的结果,才能做操作
思路
我们需要实现一个队列,将这些异步函数添加进队列并且管理它们的执行,队列具有FirstInFirstOut的特性,也就是先添加进去的会被先执行,接着才会执行下一个(注意跟栈作区别)
大家也可以类比一下jQuery的animate方法,添加多个动画也会按顺序执行
解决
模拟3个异步函数
//异步函数a
vara=function(){
returnnewPromise(function(resolve,reject){
setTimeout(function(){
resolve('a')
},1000)
})
}
//异步函数b
varb=function(data){
returnnewPromise(function(resolve,reject){
resolve(data+'b')
})
}
//异步函数c
varc=function(data){
returnnewPromise(function(resolve,reject){
setTimeout(function(){
resolve(data+'c')
},500)
})
}
解决方法一(使用then链式操作)
特点:可以满足需求,但是书写比较繁琐
代码
//链式调用
a()
.then(function(data){
returnb(data)
})
.then(function(data){
returnc(data)
})
.then(function(data){
console.log(data)//abc
})
方法二(构建队列)
特点:封装方法,可移植到别处使用
代码
//构建队列
functionqueue(arr){
varsequence=Promise.resolve()
arr.forEach(function(item){
sequence=sequence.then(item)
})
returnsequence
}
//执行队列
queue([a,b,c])
.then(data=>{
console.log(data)//abc
})
方法三(使用async、await构建队列)
同方法二,只是显得更高大上点
代码
asyncfunctionqueue(arr){
letres=null
for(letpromiseofarr){
res=awaitpromise(res)
}
returnawaitres
}
queue([a,b,c])
.then(data=>{
console.log(data)//abc
})
顺便说一句,bluebird的Promise.reduce也可以用来顺序执行函数,但是可使用的场景非常有限,一般用来读取文件信息,而以上给出的方法,不管你在异步函数中做了什么,只要函数最后返回了一个Promise对象,都可以使用
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。