1. 程式人生 > 實用技巧 >【ES6】Promise的序列和並行

【ES6】Promise的序列和並行

一、並行執行:

Promise提供了Promise.all,Promise.race,Promise.allSettled等多個Promise物件間的執行關係,如果並行執行可以用Promise.all來進行處理:

const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
});

Promise.all([promise1, promise2, promise3]).then((values) 
=> { console.log(values); }); // expected output: Array [3, 42, "foo"]

二、序列執行:

2.1、promises序列執行(問題:遇到reject時中斷執行

const serialPromises = function (promises) {
  promises.reduce((prev, next) => prev.then(next), Promise.resolve());
}

測試程式碼(均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])

結果:

上面serialPromises有個問題如果有個fn2執行reject那麼執行鏈會發生中斷

測試程式碼(包含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])

結果:

2.2、promise序列執行,遇到reject也不會中斷(問題:但是reject的方法會呼叫兩次):

const serialPromises2 = function (promises) {
  promises.reduce((prev, next) => prev.then(next).catch(next), Promise.resolve());
}

測試程式碼(2.1中包含reject的測試程式碼):

serialPromises2([fn1, fn2, fn3])

測試結果:

這個方法也有個問題是如果有fn2執行reject,那麼那個fn2會執行兩次,這是因為p.catch等價於p.then(undefined, onRejected)

2.3、promise序列執行(2.2問題解決)

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)
}

測試程式碼(2.1中包含reject的測試程式碼):

serialPromises3([fn1, fn2, fn3])

測試結果

轉自:https://www.cnblogs.com/zhuxianguo/p/11445952.html

也可以參照:https://blog.csdn.net/liushan633/article/details/84303500