Sub*_*raj 30 javascript node.js
我是这个node.js的新手..我对这个回调有点困惑..在我的应用程序内部for循环我调用异步函数调用,我想我的问题是在我得到异步调用的响应之前我的for loop get loop.
我的代码:
async.forEach(Object.keys(config), function(key, next) {
search(config[key].query, function(err, result) { //
console.log("fffffffffff="+ util.inspect(result))-------- >>>Getting undefined..
if (err) return next(err) //
var json = JSON.stringify({
"result": result
});
results[key] = {
"result": result
}
console.log("rrrrrrrr="+util.inspect(results[key]))
next() // <---- critical piece. This is how the forEach knows to continue to the next loop. Must be called inside search's callback so that it doesn't loop prematurely.
})
},
function(err) {
console.log('iterating done');
res.writeHead(200, {
'content-type': 'application/json'
});
res.end(JSON.stringify(results));
});
}
Run Code Online (Sandbox Code Playgroud)
搜索功能代码:
var matches = [];
var qrySubString = query.substring(0, 4);
client.query("select * from xxxxxxxxx where level4 ILIKE '%" + query + "%'", function(err, row1, fields) {
for (var id in row1.rows) {
var match, name;
if (query == row1.rows[id].level4) {
match = true;
name = row1.rows[id].level4;
}
else {
match = false;
name = query;
}
matches.push({
"id": id,
"name": row1.rows[id].level4,
"score": 100,
"match": match,
"type": [{
"id": "/people/presidents",
"name": "US President"
}]
})
}
callback(matches);
})
Run Code Online (Sandbox Code Playgroud)
我想在成功执行1个搜索功能后执行for循环,我想我必须使用async for loop.请指导我解决这个问题.谢谢提前..
Rob*_*b W 72
我已将代码示例缩减为以下行,以便更容易理解概念的解释.
var results = [];
var config = JSON.parse(queries);
for (var key in config) {
var query = config[key].query;
search(query, function(result) {
results.push(result);
});
}
res.writeHead( ... );
res.end(results);
Run Code Online (Sandbox Code Playgroud)
前面代码的问题是search函数是异步的,所以当循环结束时,没有调用任何回调函数.因此,列表results是空的.
要解决此问题,您必须将循环后的代码放在回调函数中.
search(query, function(result) {
results.push(result);
// Put res.writeHead( ... ) and res.end(results) here
});
Run Code Online (Sandbox Code Playgroud)
但是,由于回调函数被多次调用(每次迭代一次),因此您需要知道所有回调都已被调用.为此,您需要计算回调的数量,并检查该数量是否等于异步函数调用的数量.
要获取所有密钥的列表,请使用Object.keys.然后,为了遍历这个列表,我使用.forEach(你也可以使用for (var i = 0, key = keys[i]; i < keys.length; ++i) { .. },但这可能会产生问题,请参阅循环中的JavaScript闭包 - 简单的实际示例).
这是一个完整的例子:
var results = [];
var config = JSON.parse(queries);
var onComplete = function() {
res.writeHead( ... );
res.end(results);
};
var keys = Object.keys(config);
var tasksToGo = keys.length;
if (tasksToGo === 0) {
onComplete();
} else {
// There is at least one element, so the callback will be called.
keys.forEach(function(key) {
var query = config[key].query;
search(query, function(result) {
results.push(result);
if (--tasksToGo === 0) {
// No tasks left, good to go
onComplete();
}
});
});
}
Run Code Online (Sandbox Code Playgroud)
注意:前一个示例中的异步代码是并行执行的.如果需要以特定顺序调用函数,则可以使用递归来获得所需的效果:
var results = [];
var config = JSON.parse(queries);
var keys = Object.keys(config);
(function next(index) {
if (index === keys.length) { // No items left
res.writeHead( ... );
res.end(results);
return;
}
var key = keys[index];
var query = config[key].query;
search(query, function(result) {
results.push(result);
next(index + 1);
});
})(0);
Run Code Online (Sandbox Code Playgroud)
我所展示的是概念,您可以在实现中使用众多(第三方)NodeJS模块中的一个,例如async.
jua*_*aco 28
你已经正确诊断出你的问题了,所以工作很好.一旦你调用你的搜索代码,for循环就会继续.
我是https://github.com/caolan/async的忠实粉丝,它对我很有帮助.基本上用它你会得到类似的东西:
var async = require('async')
async.eachSeries(Object.keys(config), function (key, next){
search(config[key].query, function(err, result) { // <----- I added an err here
if (err) return next(err) // <---- don't keep going if there was an error
var json = JSON.stringify({
"result": result
});
results[key] = {
"result": result
}
next() /* <---- critical piece. This is how the forEach knows to continue to
the next loop. Must be called inside search's callback so that
it doesn't loop prematurely.*/
})
}, function(err) {
console.log('iterating done');
});
Run Code Online (Sandbox Code Playgroud)
我希望有所帮助!
我喜欢在这种情况下使用递归模式。例如,这样的事情:
// If config is an array of queries
var config = JSON.parse(queries.queryArray);
// Array of results
var results;
processQueries(config);
function processQueries(queries) {
var searchQuery;
if (queries.length == 0) {
// All queries complete
res.writeHead(200, {'content-type': 'application/json'});
res.end(JSON.stringify({results: results}));
return;
}
searchQuery = queries.pop();
search(searchQuery, function(result) {
results.push(JSON.stringify({result: result});
processQueries();
});
}
Run Code Online (Sandbox Code Playgroud)
processQueries是一个递归函数,它将从要处理的查询数组中提取一个查询元素。然后processQueries当查询完成时回调函数再次调用。processQueries当没有查询时,知道结束。
使用数组最容易做到这一点,但可以修改它以使用我想象的对象键/值。
Node.js介绍了async await在7.6所以这使得Javascript更美丽。
var results = [];
var config = JSON.parse(queries);
for (var key in config) {
var query = config[key].query;
results.push(await search(query));
}
res.writeHead( ... );
res.end(results);
Run Code Online (Sandbox Code Playgroud)
为此,search功能必须返回a promise或必须是async函数
如果未返回Promise,则可以帮助它返回Promise
function asyncSearch(query) {
return new Promise((resolve, reject) => {
search(query,(result)=>{
resolve(result);
})
})
}
Run Code Online (Sandbox Code Playgroud)
然后将其替换await search(query);为await asyncSearch(query);
| 归档时间: |
|
| 查看次数: |
88750 次 |
| 最近记录: |