NodeJS如何等待多任务完成

时间:2015-03-14 16:59:55

标签: node.js task

我想抓住一些链接,完成所有任务后,我想做点其他事情。

如何跟踪完成的任务对我来说很难。希望有人可以提供帮助。

这是我的代码:



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);
  });
}




希望有人可以帮助我。

非常感谢。

1 个答案:

答案 0 :(得分:1)

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

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上方的代码中)。

最后一件事。虽然上面的代码应该有用,但它是将promises(由.then()语句表示)与回调混合在一起。这是管理异步代码的两种不同方法。虽然如果你愿意,你可以自由地混淆它们,但为了方便阅读代码,可能有助于选择一个模式并坚持下去;)。