5

私は単純な「非同期」JS関数を持っています:

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

この asyncFunc を for ループで 5 回実行したい場合、つまり 1 秒あたり 1 ~ 5 のログを記録し、合計で 5 秒かかります。

1

2

3

4

5

jQuery の when().done() でそれができることは知っていますが、サードパーティの JS ライブラリがない環境にいる場合、 これを実現する最も簡単でエレガントな方法は何ですか?

実際には、たとえば、非同期関数の配列を受け入れる util 関数を作成したいとします。この util 関数は、渡された関数を 1 つずつ実行できます。

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

コールバックと再帰関数呼び出しを使用して同期メカニズムを使用できます。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 に答える
0

これは多くのアプローチの 1 つです。

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 に答える