node.js - NodeJS如何等待多任务完成

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

希望有人能帮助我。

非常感谢。

最佳答案

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

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 中重复的一个模式是传递给回调的第一个参数始终是错误(如果存在)。如果不是,则该参数为未定义null。实际结果作为第二个参数传递。遵循这种模式是个好主意。例如,async 希望您遵守它。如果 async.each() 中的任何任务失败(通过将非空值作为回调的第一个参数传递),async 会认为整个系列失败,并将该错误传递给系列回调(在函数 continueHere 上面的代码中)。

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

关于node.js - NodeJS如何等待多任务完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29051659/

相关文章:

node.js - 在未注册浏览器的情况下更新 cookie session

node.js - MongoDB atomic "findOrCreate": findOne, 如果不存在则插入,但不更新

javascript - Mongoose 从多个对象中提取嵌套数组到一个数组中

node.js - 使用 Passport js、Express 和 mongodb 存储 session

javascript - ui-router 中的多个 ui-view html 文件

c# - 如何在C#中将队列任务添加到线程池

c# - ContinueWith 主线程上的任务

c# - 使用 Task.wait() 应用程序挂起并且永不返回

C# - 在 for 循环中使用相同列表大小的索引位于数组边界之外

Android - 是否可以确定一个 Activity 是否从另一个任务开始?