这是我的功能
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(products)。 所以我设置了一个附加到 parseLinks 的回调,并在 for 循环之后调用它。问题出在我的 for 循环中,我每次都调用异步函数 request,所以我的回调在所有 request 调用结束之前被调用,所以我的 console .log(products) 打印一个空数组。
你知道怎么解决吗? 谢谢
最佳答案
您必须检查所有异步调用是否已完成。创建一个在所有异步工作完成后调用 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
});
}
}
您可以将 checkIfDone
的逻辑直接嵌入函数 request
中。为了清楚起见,我使用了一个单独的函数。
关于javascript - 知道我的功能何时结束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43727939/