如何同时调用异步函数并等待所有回调?

时间:2017-04-15 21:27:36

标签: javascript node.js

在nodeJS中,如何同时调用异步函数并在继续之前等待所有回调?

在下面的示例中,我希望main只有在all_resultsf1f2完成回调()时才会返回f3

function main(callback){
  var all_results = [];
  f1(function(results){
    all_results.push(result)
  });

  f2(function(results){
    all_results.push(result)
  });

  f3(function(results){
    all_results.push(result)
  });

  // when all 3 calls are complete:
  callback(all_results)
}


function f1(callback){
  ...
  callback(results);
}

function f2(callback){
  ...
  callback(results);
}

function f3(callback){
  ...
  callback(results);
}

不使用承诺。

2 个答案:

答案 0 :(得分:5)

您无法以同步方式返回异步检索的结果。因此函数 main 无法返回结果。您应该坚持使用您选择的异步方法。因此,使用回调,您还应该在调用 main 时提供回调函数:

var bitmaps =
  paths.AsParallel()
       .AsOrdered()
       .Select(getBitmap)

foreach (var bitmap in bitmaps)
{
    Dispatcher.BeginInvoke((Action)() => Images.Add(new Image { Source = bitmap }));
}

这样打电话:

function main(callback){
    var all_results = [];

    function collect(results) {
        all_results.push(results);
        // when all 3 calls are complete:
        if (all_results.length === 3) callback(all_results);
    }

    f1(collect);
    f2(collect);
    f3(collect);
}

正如其他人所说,承诺会在这种情况下产生更好的代码。

如何使用promises

假设您无法修改 f1 f2 f3 等功能,那么您可以创建 promisified 它们的版本,带有一个简单的辅助函数。完成后,包含ES6的方法main(function (all_results) { console.log(all_results); }); 将完成剩下的工作,因此代码变得非常简洁。

这是一个片段,定义了一些虚拟函数 f1 f2 f3 ,它们使用Promise.all来获得异步效果:



setTimeout




答案 1 :(得分:0)

为每个函数添加一个布尔变量,并且仅在设置完所有函数时返回:

function main(callback){
  var all_results = [];
  var finished = [false, false, false];
  f1(function(results){
    all_results.push(result)
    finished[0] = true;
  });

  f2(function(results){
    all_results.push(result)
    finished[1] = true;
  });

  f3(function(results){
    all_results.push(result)
    finished[2] = true;
  });

  var t = setInterval(checkFinished,1000);
  function checkFinished(){
      if(finished[0] && finished[1] && finished[2]){
          clearInterval(t)
          callback(all_results)
      }
  }
}