NodeJS如何等待多任务完成

NodeJS how to wait multi tasks complete

我想抓取一些链接,完成所有任务后,我想做点别的。

如何跟踪已完成的任务对于 me.Hope 有人可以提供帮助。

这是我的代码:

var urlList=[];
//Ready file lines
lineReader.eachLine('url.txt', function(line) {

  console.log('url is :'+line);
  urlList.push(line);
  
}).then(function(){//After Read,begin to proceed each line

 console.log('read done!begin collect');

 async.each(urlList,function(line){
  console.log('begin line :'+line);

  //down each url
    download(line,function(data,cb){

     var $=cheerio.load(data);//load cheerio

     var title=$('head>title').text();//get title

   console.log('title is '+title);
  });
 });

   //At here i want to track whether all urls has been download,and i can do something else
   if(/* allproceed */)
   {
      console.log('Task all done!Begin Next');
   }
    

});

function download(url, callback) {
  http.get(url, function(res) {
    var data = "";
    res.on('data', function (chunk) {
      data += chunk;
    });
    res.on("end", function() {
      callback(data);
    });
  }).on("error", function(e) {
    console.log("Got error: " + e.message);
    callback(null);
  });
}

希望有人能帮助我。

非常感谢。

我已经对您的代码进行了一些修复,请查看以下结果:

var urlList=[];
//Ready file lines
lineReader.eachLine('url.txt', function(line) {

  console.log('url is :'+line);
  urlList.push(line);

}).then(function(){//After Read,begin to proceed each line

    console.log('read done!begin collect');

    async.each(urlList,function(line, callback){
        console.log('begin line :'+line);

        //down each url
        download(line,function(err, data){
            if (err) {
                return callback(err);
            }

            var $=cheerio.load(data);//load cheerio

            var title=$('head>title').text();//get title

            console.log('title is '+title);

            callback(null, title);
        });
    }, function continueHere(err) {
       //At here i want to track whether all urls has been download,and i can do something else
       console.log('Task all done!Begin Next');
    });
});

function download(url, callback) {
  http.get(url, function(res) {
    var data = "";
    res.on('data', function (chunk) {
      data += chunk;
    });
    res.on("end", function() {
      callback(null, data);
    });
  }).on("error", function(e) {
    console.log("Got error: " + e.message);
    callback(e);
  });
}

一些需要特别注意的事情:

您已经非常接近您的答案了。 async.each() 是一个可以用来完成工作的工具,但您还没有正确使用它。您传递给它的迭代器函数,即为 urlList 中的每个项目调用的函数,接受一个回调,如果该迭代的作业完成,您可以调用该回调。我添加了那个回调。

async.each() 也有第三个参数:当所有任务完成时调用的函数。在此函数中,您可以放置​​继续应用程序其余部分的代码。

关于使用回调:在 node.js 中重复的模式是传递给回调的第一个参数始终是一个错误,如果存在的话。如果不是,则该参数为 undefinednull。实际结果作为第二个参数传递。遵循这种模式是个好主意。例如,async 希望您遵守它。如果 async.each() 中的任何任务失败(通过将非空值作为回调的第一个参数传递),async 认为整个系列失败,并将该错误传递给系列回调(在函数 continueHere 上面的代码中)。

最后一件事。虽然上面的代码应该可以工作,但它混合了承诺(由 .then() 语句表示)和回调。这是管理异步代码的两种不同方式。尽管您可以根据需要随意混合它们,但为了代码的可读性,选择一种模式并坚持下去可能会有所帮助 ;)。