好吧,你的代码有几个问题,但是很容易解决如果你很小心的话,我会指导你解决它们。
第一个:
你是
要始终排队,这是在队列中获取相同数据的根本原因:
queries.push(req.body.searchTerm); // searchTerm being '1'
... // Do more logic until googleEntityAnalyze
entities.forEach(entity => {
queries.push(entity.name);
resolve({ entity });
});
// Assume entities as [2, 3]
现在您的队列是
[1,2,3]
,作为第一个参数为1。
然后从以下位置重做查询逻辑:
async function onQueueSearch() {
for(i = 0; i < queries.length; i++) {
return await sentimentAnalyze(queries[i]);
// queries[i].splice(i, 1);
}
if(queries.length === 0 ) {
console.log("queries length is zero...");
}
}
for循环的返回将中断循环并返回第一次执行,这将是
queries[0] === 1
因此,要解决此问题,请使用以下方法使数组保持先进先出:
queries.unshift(req.body.searchTerm);
entities.forEach(entity => {
queries.unshift(entity.name);
resolve({ entity });
});
这将使您的查询在到达[3,2,1]时保持有序,而不是[1,2,3],现在您可以使用
queries.pop()
相反。
queries.unshift(4); // where queries was [3,2,1], will be [4,3,2,1]
queries.pop(); // 1
将情绪分析更改为:
async function onQueueSearch(){
if(queries.length === 0 ) {
console.log("queries length is zero...");
return; // Return something if empty!
}
return await sentimentAnalyze(queries.pop());
// This will extract the next in queue and remove it from queries
}
您正在使用一个iterval来连续调用查询,问题是:
setInterval(async function() {
results = await onQueueSearch();
}, 3000);
“估计”
重新执行前完成查询所需的时间。使用上面的unshift和pop查询,您可以完成这项工作,但是,您需要一个更优雅的解决方案。
带有NodeJS版本<10+:
const queries = [1];
let counter = 0; // Just to keep track
async function reRunQueries(){
counter++;
console.log(`queries #${counter}: `, queries);
results = await onQueueSearch();
console.log('Results: ', results);
if(!!queries.length){
return await reRunQueries();
}else{
return results;
}
}
async function onQueueSearch(){
return await longQuery(queries.pop());
}
async function longQuery(param){
if(param === 6){
// Use this as stop signal!
return param;
}else{
queries.unshift(++param);
return param;
}
}
const RES = reRunQueries();
RES.then(result => {
console.log('RES: ', result);
})
知道递归的停止信号很重要,否则它永远不会结束。
使用Iterable生成器:
const queries = [];
let counter = 0; // Just to keep track
// EMULATE EXPRESS JS call ========================
const req = { body: { searchTerm: 1 } };
const res = {send: (val) => console.log('RECEIVED: ', val)};
const router = {
post: (route, callback) => callback(req, res)
}
router.post('/', async (req, res) => {
// Assign first query
queries.push(req.body.searchTerm);
// Invoke the async iterator
const results = await queryIterator(queries);
res.send(results);
});
// The Above is for nodeJS direct testing only,
// > you can plug it into your own router.post declaration "as is"
// -----------------------------------------
// Define functions for Async Iterator -----
async function* queryGenerator() {
while (true) {
yield await onQueueSearch(queries.pop());
}
}
async function queryIterator(queries) {
for await (const result of queryGenerator()) {
console.log('Iterating... ', result);
console.log(`On Queue Searches #${++counter}: `, queries);
if (!queries.length) {
return result;
}
}
}
// ------------------------------------------------------------
// Emulate your current async requests using queries array ----
async function onQueueSearch(param) {
return await longQuery(param);
}
async function longQuery(param) {
if (param === 6) {
// Use this as stop signal!
return Promise.resolve(param);
} else {
queries.unshift(++param);
return Promise.resolve(param);
}
}
/*
Iterating... 2
On Queue Searches #1: [ 2 ]
Iterating... 3
On Queue Searches #2: [ 3 ]
Iterating... 4
On Queue Searches #3: [ 4 ]
Iterating... 5
On Queue Searches #4: [ 5 ]
Iterating... 6
On Queue Searches #5: [ 6 ]
Iterating... 6
On Queue Searches #6: []
RECEIVED: 6
*/