Promise提供了Promise.all,Promise.race,Promise.allSettled等多個Promise對象間的運行關系,如果並行運行可以用Promise.all來進行處理,如果要串行運行可以用數組的reduce來進行處理,處理代碼如下:
const serialPromises = function (promises) {
promises.reduce((prev, next) => prev.then((preVal) => next(preVal)), Promise.resolve());
}
測試代碼
const fn1 = function (args) {
console.log('fn1',args)
return Promise.resolve('111')
}
const fn2 = function (args) {
console.log('fn2',args)
return Promise.resolve('222')
}
const fn3 = function (args) {
console.log('fn3',args)
return Promise.resolve('333')
}
serialPromises([fn1, fn2, fn3])
測試結果:
fn1 undefined fn2 111 fn3 222
上面serialPromises有個問題如果有個fn2執行reject那么執行鏈會發生中斷
測試代碼
const fn1 = function (args) {
console.log('fn1',args)
return Promise.resolve('111')
}
const fn2 = function (args) {
console.log('fn2',args)
return Promise.reject('222')
}
const fn3 = function (args) {
console.log('fn3',args)
return Promise.resolve('333')
}
serialPromises([fn1, fn2, fn3])
測試結果
fn1 undefined fn2 111 Uncaught (in promise) 222
改進一下
const serialPromises2 = function (promises) {
promises.reduce((prev, next) => prev.then(next).catch(next), Promise.resolve());
}
測試代碼
const fn1 = function (args) {
console.log('fn1',args)
return Promise.resolve('111')
}
const fn2 = function (args) {
console.log('fn2',args)
return Promise.reject('222')
}
const fn3 = function (args) {
console.log('fn3',args)
return Promise.resolve('333')
}
serialPromises2([fn1, fn2, fn3])
測試結果
fn1 undefined fn2 111 fn2 222 fn3 222
這個方法也有個問題是如果有fn2執行reject,那么那個fn2會執行兩次,這是因為p.catch等價於p.then(undefined, onRejected)
我們再次改進
const serialPromises3=function(promises){
const process=function(i,args){
const curr=promises[i]
const next=function(res){process(i+1,res)}
if(curr)curr(args).then(next).catch(next)
}
process(0)
}
測試代碼
const fn1 = function (args) {
console.log('fn1',args)
return Promise.resolve('111')
}
const fn2 = function (args) {
console.log('fn2',args)
return Promise.reject('222')
}
const fn3 = function (args) {
console.log('fn3',args)
return Promise.resolve('333')
}
serialPromises3([fn1, fn2, fn3])
測試結果
fn1 undefined fn2 111 fn3 222
至此問題終於解決了!
