知识点

异步流程控制

题目

完成函数driveCustomers,它接受不定数量的参数,这是参数都是函数,每个函数代表一个人。这些函数都接受一个回调函数作为参数,当回调函数被调用的时候说明这个人已经上车了,回调函数会被传入人名。例如:

const MissLi = (callback) => {
  setTimeout(() => {
    callback(\'MissLi\')
  }, 4000) // 上车时间不一定
};

const MrWang = (callback) => {
  setTimeout(() => {
    callback(\'MrWang\')
  }, 3000) // 上车时间不一定
};

const drive = v => console.log(v);

driveCustomers(MissLi, MarWang, ...)

完成driveCustomers函数,它的作用是:当人都到齐以后,按上车的时间顺序把人名放到一个数组里面然后传给drive函数,正式开车。例如drive([\'MrWang\', \'MissLi\'])

实现

其实这是一个异步函数,首先就想到了用Promise控制,callback是我们可以自行控制的,将传入的函数都改造成为Promise,当callback被调用时,改变Promise的状态为resolve,然后利用Promise.all数组控制所有的队列

要注意一点,Promise.all返回数组成员的顺序是按照原Promise数组顺序返回的,与执行顺序无关,不满足题目的要求

const driveCustomers = (...func) => {
  let result = [];
  const promises = func.map(v => new Promise(resolve => {
    v(name => {
      result.push(name);
      resolve(name);
    })
  }));
  Promise.all(promises).then(v => { drive(result) });
};

另一种方法

其实我又陷入了之前的思维定式,实际没有必要使用Promise,因为MissLi就是一个异步函数,我们在callback执行的时候就可以进行一系列操作(只是这种操作不太方便函数返回值)

const driveCustomers = (...func) => {
  let result = [];
  func.forEach(v => {
    v(name => {
      result.push(name);
      result.length === func.length && drive(result)
    })
  });
};

参考

收藏 打印