我想抓取一些链接,完成所有任务后,我想做点其他事情。
如何跟踪已完成的任务对我来说很难。希望有人能提供帮助。
这是我的代码:
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/