Node.js 中的异步函数
Async Function in Node.js
我的 Node.js API 中有一个端点 returns JSON Google-Search-[=24] 提供的结果数组=]scraper 图书馆.
app.get('/google_image_search', (req, res) => {
var options = {
query: 'grenouille',
age: 'y', // last 24 hours ([hdwmy]\d? as in google URL)
limit: 10,
params: {} // params will be copied as-is in the search URL query string
};
var results = [];
scraper.search(options, function(err, url, meta) {
sem.take(function() {
if(err) throw err;
var result = {
title: meta.title,
meta: meta.meta,
description: meta.desc
}
results.push(result);
sem.leave();
});
})
console.log(results);
res.json({
results
});
})
我需要 console.log(results) 和 res.json({ results }) 在 scraper.search 函数完成后发生。它目前总是返回一个空数组。
为每个结果调用传递给 scraper.search() 函数的函数。所以如果有 10 个结果函数运行 10 次,这就是为什么我要等到数组已满才发送响应。
我试过在不同的地方使用信号量和互斥锁,但没有成功。任何建议表示赞赏。
这已通过使用 LIMIT 变量来检查我的结果数组来解决。在下面标记为正确的答案中概述。
感谢大家的意见。
I need the console.log(results) and the res.json({ results }) to happen after the scraper.search function is done.
将它放在最里面的回调中 scraper.search()
。
scraper.search(options, function(err, url, meta) {
if(err) throw err;
var result = {
title: meta.title,
meta: meta.meta,
description: meta.desc
};
results.push(result);
console.log(result);
res.json({results});
});
每次回调运行时都会调用console.log()
和res.json()
。如果您只想在 10 个结果或其他结果之后执行此操作,请添加代码以检查条件并且仅在正确的时间 运行 console.log()
and/or res.json()
。
您也可以查看 async
/await
之类的内容,但鉴于您发布的代码,以上可能是最增量的解决方案。
现在 console.log()
和 res.json()
的问题在于,它将使用异步回调的函数视为同步函数。
Trott 的回答是正确的,但是有一个每次都递增的变量如何,然后当它等于 10(或 9,取决于你如何实现它)时,运行 你的完成代码。您也可以只计算数组中的元素。
app.get('/google_image_search', (req, res) => {
var options = {
query: 'grenouille',
age: 'y', // last 24 hours ([hdwmy]\d? as in google URL)
limit: 10,
params: {} // params will be copied as-is in the search URL query string
};
var results = [];
scraper.search(options, function(err, url, meta) {
sem.take(function() {
if(err) throw err;
var result = {
title: meta.title,
meta: meta.meta,
description: meta.desc
}
results.push(result);
sem.leave();
});
if(results.length==10) {
console.log(results);
res.json({
results
});
}
})
})
将 res.send
置于回调之外将导致类似于 this problem 的竞争条件。 google-search-scraper
库的一个缺点是它不是为收集结果而设计的。
这应该是固定的:
var LIMIT = 10;
var options = { limit: LIMIT, ... };
var results = [];
var errs = [];
var resultsCount = 0;
function resultsHandler() {
if (errs.length) {
// handle error
} else
res.json({ results });
}
scraper.search(options, function resultHandler(err, url, meta) {
if (err)
errs.push(err);
else {
var result = {
title: meta.title,
meta: meta.meta,
description: meta.desc
};
results.push(result);
});
resultsCount++;
if (resultsCount === LIMIT)
resultsHandler();
});
如果 search
在某些情况下可能不调用回调,这将不起作用。
我的 Node.js API 中有一个端点 returns JSON Google-Search-[=24] 提供的结果数组=]scraper 图书馆.
app.get('/google_image_search', (req, res) => {
var options = {
query: 'grenouille',
age: 'y', // last 24 hours ([hdwmy]\d? as in google URL)
limit: 10,
params: {} // params will be copied as-is in the search URL query string
};
var results = [];
scraper.search(options, function(err, url, meta) {
sem.take(function() {
if(err) throw err;
var result = {
title: meta.title,
meta: meta.meta,
description: meta.desc
}
results.push(result);
sem.leave();
});
})
console.log(results);
res.json({
results
});
})
我需要 console.log(results) 和 res.json({ results }) 在 scraper.search 函数完成后发生。它目前总是返回一个空数组。
为每个结果调用传递给 scraper.search() 函数的函数。所以如果有 10 个结果函数运行 10 次,这就是为什么我要等到数组已满才发送响应。
我试过在不同的地方使用信号量和互斥锁,但没有成功。任何建议表示赞赏。
这已通过使用 LIMIT 变量来检查我的结果数组来解决。在下面标记为正确的答案中概述。
感谢大家的意见。
I need the console.log(results) and the res.json({ results }) to happen after the scraper.search function is done.
将它放在最里面的回调中 scraper.search()
。
scraper.search(options, function(err, url, meta) {
if(err) throw err;
var result = {
title: meta.title,
meta: meta.meta,
description: meta.desc
};
results.push(result);
console.log(result);
res.json({results});
});
每次回调运行时都会调用console.log()
和res.json()
。如果您只想在 10 个结果或其他结果之后执行此操作,请添加代码以检查条件并且仅在正确的时间 运行 console.log()
and/or res.json()
。
您也可以查看 async
/await
之类的内容,但鉴于您发布的代码,以上可能是最增量的解决方案。
现在 console.log()
和 res.json()
的问题在于,它将使用异步回调的函数视为同步函数。
Trott 的回答是正确的,但是有一个每次都递增的变量如何,然后当它等于 10(或 9,取决于你如何实现它)时,运行 你的完成代码。您也可以只计算数组中的元素。
app.get('/google_image_search', (req, res) => {
var options = {
query: 'grenouille',
age: 'y', // last 24 hours ([hdwmy]\d? as in google URL)
limit: 10,
params: {} // params will be copied as-is in the search URL query string
};
var results = [];
scraper.search(options, function(err, url, meta) {
sem.take(function() {
if(err) throw err;
var result = {
title: meta.title,
meta: meta.meta,
description: meta.desc
}
results.push(result);
sem.leave();
});
if(results.length==10) {
console.log(results);
res.json({
results
});
}
})
})
将 res.send
置于回调之外将导致类似于 this problem 的竞争条件。 google-search-scraper
库的一个缺点是它不是为收集结果而设计的。
这应该是固定的:
var LIMIT = 10;
var options = { limit: LIMIT, ... };
var results = [];
var errs = [];
var resultsCount = 0;
function resultsHandler() {
if (errs.length) {
// handle error
} else
res.json({ results });
}
scraper.search(options, function resultHandler(err, url, meta) {
if (err)
errs.push(err);
else {
var result = {
title: meta.title,
meta: meta.meta,
description: meta.desc
};
results.push(result);
});
resultsCount++;
if (resultsCount === LIMIT)
resultsHandler();
});
如果 search
在某些情况下可能不调用回调,这将不起作用。