实现Promise串行函数

函数描述

该函数作用类似Promise.all,不同的是Promise.all中的promise是并行的,而此函数的promise 要依次执行,类似这样

function async fun(arr){
    const results = [];
    await arr[0];
    await arr[1];
    await arr[2];
    ...
    //返回所有promise的结果组成的数组
    return results;
}
复制代码

实现

目前能确定的是此函数的参数是个数组,返回值是promise。要实现串行,那么数组的元素就不能是promise,而应该是返回值是promise的函数,因为promise一旦被创建后就开始运行了。

//promise串行函数
function serialPromises(arr=[]) {
  const result = [];
  return new Promise((resolve, reject) => {
      resolve(result)
  });
}

//返回值是promise的函数
function promiseCreator(time){
  return new Promise((resolve, reject) => {
    settimeout(()=>{
      resolve(time)
    }, time*1000)
  })
}
//使用示例
const  arr = [
  promiseCreator.bind(null, 1),
  promiseCreator.bind(null, 3),
  promiseCreator.bind(null, 5),
  promiseCreator.bind(null, 4),
  promiseCreator.bind(null, 2),
];
serialPromises(arr).then(console.log).catch(console.error);
复制代码

接下来完善serialPromises的函数体。
整体思路就是当前promisethen函数总调用下一个promiseCreator,直到最后一个promise

function serialPromises(arr=[]) {
  //promise的结果数组
  const result = [];
  const arrLength = arr.length;
  return new Promise((resolve, reject) => {
    let index = 1;
    //then的回调函数,通过该函数实现promise依次调用
    function resolvePromise(v) {
      result.push(v);
      //不是最后一个
      if (index + 1 < arrLength) {
        //调用index下标的函数生成下一个promise
        arr[index++]().then(resolvePromise);
      } else {
        //最后一个promise完成后,resolve返回的promise
        arr[index]().then((v) => {
            result.push(v);
            resolve(result);
          }).catch((err) => {
            reject(err);
          });
      }
    }
    if (arrLength === 0) {
      resolve(result)
    } else {
      //触发第一个promise
      arr[0]().then(resolvePromise);
    }
  });
}
复制代码

测试一下

function promiseCreator(time){
  return new Promise((resolve, reject) => {
    setTimeout(()=>{
      resolve(time)
    }, time*1000)
  })
}
const  arr = [
  promiseCreator.bind(null, 1),
  promiseCreator.bind(null, 3),
  promiseCreator.bind(null, 5),
  promiseCreator.bind(null, 4),
  promiseCreator.bind(null, 2),
];
serialPromises(arr).then(console.log).catch(console.error);//大概15秒后打印出 [1,3,5,4,2]
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享