使用array.reduce顺序触发无承诺的异步函数

时间:2018-07-18 15:42:22

标签: javascript node.js asynchronous es6-promise

我可以像下面这样一个接一个地执行异步函数:

function asyncFn(e, cb) {
  return new Promise((res, rej) => {
    setTimeout(() => {
      console.log(e);
      res();
    }, 1000);
  });
}

var arr = [1,2,3,4,5];
arr.reduce(
  (chain, e) => chain.then(()=>asyncFn(e)),
  Promise.resolve()
);

是否可以使用回调而不是解决诺言来做同样的事情?

1 个答案:

答案 0 :(得分:-2)

当然可以,但是要复杂一些:

const logLater = (msg, time, cb) => setTimeout(() => (console.log(msg), cb()), time);

const arr = [1, 2, 3, 4, 5];

arr.reduceRight((next, el) => () => logLater(el, 1000, next), () => console.log("all done!"))();

或多行:/:

function logLater(msg, time, cb) {
 setTimeout(function() {
   console.log(msg);
   cb();
 }, time);
}

const arr = [1, 2, 3, 4, 5];

arr.reduceRight(function(next, el) {
 return function current() {
   logLater(el, 1000, next);
 };
}, function() { })();

建立回调链的过程是向后的,因此记录5将被包装在一个函数中,该函数将在调用时进行记录,然后将该函数传递到4的包装器中,该包装器将在调用时进行调用记录了44的包装将作为next传递到3的包装,依此类推。


但是,如果您只想对数组的所有元素执行某项任务并等待上一个回调,则可以使用一个调用自身的函数来做到这一点:

function logLater(msg, time, cb) {
 setTimeout(function() {
   console.log(msg);
   cb();
 }, time);
}

const arr = [1, 2, 3, 4, 5];

(function  next(i) {
   logLater(arr[i], 1000, function done() {
     if(i < arr.length - 1) next(i + 1);
   });
})(0);