5

我有一个简单的“异步”JS 函数:

function asyncFunc(i) {
    setTimeout(function () {
        console.log(i);
    }, 1000);
}

如果我想在 for 循环中执行此 asyncFunc 5 次,即每秒记录 1 - 5 次,总共花费 5 秒。

1

2

3

4

5

我知道 jQuery 的 when().done() 可以做到这一点,但是如果我在没有 3rd 方 JS 库的环境中, 那么实现这一点的最简单和优雅的方法是什么?

实际上例如我想写一个 util 函数,它接受一个异步函数数组,并且这个 util 函数可以一个一个地执行传入的函数:

function execAsyncTasks([asyncTask1, asyncTask2, asyncTask3]) {
    asyncTask1();
    // Wait until asyncTask1 finished
    asyncTask2();
    // Wait until asyncTask2 finished
    asyncTask3();
    // Wait until asyncTask3 finished
}
4

4 回答 4

9

您的所有任务都必须实现某种回调机制,因为这是您知道异步任务已完成的唯一方法。有了它,您可以执行以下操作:

function executeTasks() {
    var tasks = Array.prototype.concat.apply([], arguments);
    var task = tasks.shift();
    task(function() {
        if(tasks.length > 0)
            executeTasks.apply(this, tasks);
    });
}

executeTasks(t1, t2, t3, t4);

演示

于 2012-11-27T11:47:42.367 回答
2

您可以使用异步模块:

https://github.com/caolan/async

async.parallel([
    function(){ ... },
    function(){ ... }
], callback);

async.series([
    function(){ ... },
    function(){ ... }
]);
于 2012-11-27T11:35:13.653 回答
0

这是许多方法中的一种

function execAsyncTasks(asyncTask1, asyncTask2, asyncTask3) {
  var count = 0;

  function nextCommand() {
    switch (count) {
      case 0:
        asyncTask1();
        break;
      case 1:
        asyncTask2();        
        break;
      case 2:
        asyncTask3();
      default:
        return;
    }
    count++;
    setTimeout(nextCommand, 1000);
  }
  nextCommand();
}
于 2012-11-27T11:38:01.287 回答
0

你可以有一个使用回调和递归函数调用的同步机制:见 http://jsfiddle.net

function asyncFunc(i, callback) {
  setTimeout(function() {
    document.body.innerHTML += '<p>' + i + '</p>';
    callback();
  }, 1000);
}

var args = [0, 1, 2, 3, 4];

function loopThroughArgs(callback) {
  if (args.length == 0) {
    callback();
  } else {
    asyncFunc(args[0], function() {
      args.splice(0, 1); //remove the first item from args array
      loopThroughArgs(callback);
    });
  }
}

loopThroughArgs(function() {
  document.body.innerHTML += '<p>done !</p>';
});

于 2012-11-27T11:52:25.913 回答