在非阻塞序列中循环执行异步回调

时间:2016-03-15 23:29:48

标签: javascript loops nonblocking

在此处点击墙壁试图让它工作 - console.log输出应为0, 1, 2, 3。它应该基本上循环遍历数组并以非阻塞方式依次调用函数(如果传入则等待done()):

var array = [

  function(done) {
    setTimeout(function() {
       console.log(0);
      done();
    }, 2000);
  },

  function(done) {
    setTimeout(function() {
      console.log(1);
      done();
    }, 200);
  },

  function() {
    // This one is synchronous and doesn't need
    // to use done()
    console.log(2);
  },

  function(done) {
    setTimeout(function() {
      console.log(3);
      done();
    }, 70);
  }

];

我不介意解决方案是使用生成器,Promise,还是其他东西。我在想这个功能可以包含以下内容:

function fnWrapper(fn) {
  return new Promise(function(resolve) {
    if (fn.length >= 1) {
      // If the done callback is passed in.
      fn(resolve);
    } else {
      fn();
      resolve();
    }
  });
}

array.reduce((promise, fn) => promise.then(fnWrapper(fn)), Promise.resolve());

http://codepen.io/ferahl/pen/wGoRZN?editors=0010

但到目前为止,我尝试使用生成器或promise / reduce进行循环操作非常破碎。有任何想法吗?感谢。

更新:PS我无法控制在

中调用done()的异步方法

2 个答案:

答案 0 :(得分:3)

这是一个使用promises的解决方案(和EOF来串联运行函数):

Array.prototype.reduce

CodePen

答案 1 :(得分:0)

我意识到为了让我的承诺按顺序执行,我需要返回一个函数,该函数在then中返回一个promise(而不是将promise本身传递给它):

function fnWrapper(fn) {
  return new Promise(function(resolve) {
    if (fn.length >= 1) {
      // If the done callback is passed in.
      fn(resolve);
    } else {
      fn();
      resolve();
    }
  });
}

array.reduce((promise, fn) => promise.then(() => fnWrapper(fn)), Promise.resolve());

Codepen:http://codepen.io/ferahl/pen/wGoRZN?editors=0010