异步运行三个函数并等到三个函数完成

时间:2017-01-19 18:09:11

标签: node.js asynchronous

在以下名为start的函数中,连续调用三个函数。执行完所有函数后,再次调用容器函数start

有没有办法,我可以并行或异步运行这三个函数,当三个函数完成后,再次调用start方法。

function start(){
    resolveErrorQueue((err,data)=>{
            if(err)
                console.log(err);
            else{
                checkIfAlive((err,data) => {
                   if(err)
                       console.log(err);
                   else{
                      prepareServer((err,data) => {
                        if(err)
                            console.log(err);
                        else
                            start();
                      }); 
                   }                    
                });
            }               
    });
}

5 个答案:

答案 0 :(得分:1)

最干净的方法是使用promise库。例如,在Q中你可以使用q.all函数

Q.all([getFromDisk(), getFromCloud()]).done(function (values) {
    assert(values[0] === values[1]); // values[0] is fromDisk and values[1] is fromCloud
});

如果您想在没有promises的情况下执行此操作,则可以创建一个全局变量,每次异步函数完成时该变量都会递增。然后调用3个异步函数,并在回调中增加全局变量。如果需要,您还可以全局存储返回数据。

然后,您可以使用while循环或setInterval来检查3个函数是否全部返回。

答案 1 :(得分:1)

使用async模块' parallel

async.parallel([resolveErrorQueue, checkIfAlive, prepareServer], (err, results) => {
  if (err)
    console.error(err);
  else
    start();
});

由于您的方法似乎与回调async模块一起使用,因此非常适合。如果方法也支持承诺,那么也可以这样做,例如,使用Bluebird Promise.join或Q.all(如@ user2263572所述)。

答案 2 :(得分:1)

我同意user2263572的answer你应该使用promises。使用ES6 Promises甚至更简单,自v4.7.1起,Node.js本身就支持它。

这是一个有效的例子:

function resolveErrorQueue(resolve, reject) {
    setTimeout(() => {
        resolve("no errors in queue");
    }, 1000);
}

function checkIfAlive(resolve, reject) {
    setTimeout(() => {
        resolve("server is alive");
    }, 999);
};

function prepareServer(resolve, reject) {
    setTimeout(() => {
        resolve("server is prepared");
    }, 1001);
};

var counter = 0;
function start() {
    Promise.all([new Promise(resolveErrorQueue), new Promise(checkIfAlive), new Promise(prepareServer)]).then(values => {
        console.log(`${++counter}: ${values}`);
        start();
    });
}
start();

答案 3 :(得分:0)

不完全确定你的目标是什么,但也许是这样的?

function start(){
    var leftToRun = 3;

    resolveErrorQueue((err,data)=>{
        if(err)
            console.log(err);
        else{
            if (--leftToRun === 0) { start(); }
        }
    });

    checkIfAlive((err,data) => {
        if(err)
            console.log(err);
        else{
            if (--leftToRun === 0) { start(); }
        }
    });

    prepareServer((err,data) => {
        if(err)
            console.log(err);
        else
            if (--leftToRun === 0) { start(); }
    }); 
}

它实际上不会并行运行,因为Node只在一个线程中运行您的代码,但如果您调用的操作是异步的,则函数不必按顺序完成。

答案 4 :(得分:0)

您可以在nodejs中使用async.series()方法。 async是一个模块,它提供了在nodejs中执行异步方法的各种方法。

例如:

async.series([function1,function2,function3],function(err,result{
if(err){
      // do here if error occured. 
  }
      console.log(result);
     // DO here what you want to do after function1, function2 and function3 completion. 
});


var function1 = function(cb){
     // do here in function1 
        cb(null,'ok');
  };

var function2 = function(cb){
    // do here in function2 
        cb(null,'ok');
  };

var function3 = function(cb){
   // do here in function3 
        cb(null,'ok');
  };

您可以在async.series()中添加任意数量的函数作为参数。