2015-03-14 2 views
1

Я хочу, чтобы пауки некоторых ссылок и после всех выполненных задач я хочу сделать что-то еще.NodeJS как дождаться выполнения нескольких задач

Как отслеживать выполненные задачи трудно для меня. Надеюсь, кто-то может помочь.

вот мой код:

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 
 

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

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

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

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

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

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

 
    //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

Я сделал некоторые исправления в коде см ниже результат:

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() также принимает третий аргумент: функция, которая вызывается, когда все задачи завершены. В этой функции вы можете поместить код, который продолжит остальную часть вашего приложения.

Что касается использования обратного вызова: шаблон, повторяемый на узле.js, состоит в том, что первый аргумент, переданный обратному вызову, всегда является ошибкой, если таковой существует. Если нет, этот аргумент undefined или null. Фактический результат передается как второй аргумент. Это хорошая идея, чтобы следовать этой схеме. async, например, ожидает, что вы повинуетесь ему. Если какая-либо из задач в async.each() сбой (путем передачи ненулевого значения в качестве первого аргумента для обратного вызова), async считает, что вся серия не выполнена, и передает эту ошибку на обратный вызов серии (в коде выше функция continueHere).

Последнее изделие. Хотя код выше должен работать, он смешивает обещания (обозначенные оператором .then()) с обратными вызовами. Это два разных способа управления асинхронным кодом. Хотя вы можете смешать их, если хотите, для удобочитаемости кода, это может помочь выбрать один patter и придерживаться его;).

+0

Большое спасибо, этот код работает отлично, я многому научился! –

Смежные вопросы