知道我的function何时结束

这是我的function

function parseLinks(links, callback) { var products = []; for (var i = 0; i < links.length; i++) { request(links[i], function (error, response, body) { var product; if (!error && response.statusCode == 200) { var $ = cheerio.load(body); // title var title = $('h1').text(); if (!title) var title = $('title').text(); var description = $('meta[name="description"]').attr('content'); product = new Product(links[0].trim(), title.trim(), description.trim()); products.push(product); } }); } callback(products) // the callback only do a console.log(products) } 

之后,我想做一个显示所有产品的console.log(产品) 。 所以我设置了一个附加到parseLinks的callback函数,并在for循环之后调用它。 问题是在我的for循环中,我每次调用asynchronous函数请求 ,所以我的callback在所有的请求调用结束之前调用,所以我的console.log(产品)打印一个空的数组。

你知道如何解决这个问题吗? 谢谢

你必须检查是否所有的asynchronous调用已经完成。 创build一个在完成所有asynchronous工作时调用callback的内部函数:

 function parseLinks(links, callback) { var products = [], numberOfItems = links.length; // numbers of linkes to be parsed function checkIfDone() { // this function will be called each time link is parsed numberOfItems--; // decrement the numberOfItems (number that tells us how many links left) if(numberOfItems === 0) // if there are none left (all links are parsed), then call callback with the resultant array. callback(products); } for (var i = 0; i < links.length; i++) { request(links[i], function (error, response, body) { // ... checkIfDone(); // everytime a link is parsed, call checkIfDone }); } } 

您可以直接在函数requestembeddedcheckIfDone的逻辑。 为了清晰,我使用了一个单独的函数

最好的方法是使用async

 var async = require("async"); function parseLinks(links, callback) { var products = []; async.forEach(links, function(link, done) { request(link, function (error, response, body) { var product; if (!error && response.statusCode == 200) { var $ = cheerio.load(body); // title var title = $('h1').text(); if (!title) var title = $('title').text(); var description = $('meta[name="description"]').attr('content'); product = new Product(links[0].trim(), title.trim(), description.trim()); products.push(product); } done(); }); }, function() { callback(products); }); } 

您可以使用asnyc模块中的async.each

简化代码:

 function parseLinks(links, callback) { var products = []; async.each(links, function(link, requestCallback) { request(links[i], function(error, response, body) { //... rest of your code requestCallback(); //Request has ended }); }, function(err) { //All requests ended! callback(); }); }