我遇到过一种情况,我在for循环中有一个异步函数。我已完成先决条件搜索,现在知道forEach()或map()可能是我需要的解决方案。但是所有的例子我只看到console.log()每个异步函数的结果。如何将每个异步函数的结果设置为变量,然后只返回变量?
这里有一些我正在做的精简代码:(顺便说一句,这都在节点中)
var clients={
"102323":{stuff about this client},
"242341":{stuff about that client}
};
var messages={};
for (var id_client in clients) {
mysql.query("SELECT * FROM messages WHERE id_client='"+id_client+"' ORDER BY date", function(err, rows) {
if (typeof rows !== 'undefined') messages[id_client]=rows;
});
}
//do other stuff with messages variable
这样,messages
可预测为空。据我所知。
但即使我将其转换为使用map()而不是for(),就像这样......
var messages={};
Object.keys(clients).map(function(id_client){
mysql.query("SELECT * FROM messages WHERE id_client='"+id_client+"' ORDER BY date", function(err, rows) {
if (typeof rows !== 'undefined') messages[id_client]=rows;
});
});
...消息最终为空。
最后,我想要注意的是我确实知道如何将mysql.query()包装到带有回调的另一个函数中,以及解决整个异步事件的所有问题。如果在循环内部进行迭代,我只是不知道这一切是如何工作的。
答案 0 :(得分:3)
你可以使用Promise。
var messages = {};
Promise.all(Object.keys(clients).map((id_client) => {
return new Promise((resolve, reject) => {
mysql.query("SELECT * FROM messages WHERE id_client='" + id_client + "' ORDER BY date", function(err, rows) {
if (typeof rows !== 'undefined') {
messages[id_client] = rows;
resolve(rows);
}
});
});
})).then(results => {
console.log(messages);
});
答案 1 :(得分:1)
这是一个纯JavaScript版本:
var clients={
"102323":{stuff about this client},
"242341":{stuff about that client}
};
var messages={};
var cnt = 2;
function done() {
console.log(messages);
}
mysql.query("SELECT * FROM messages WHERE id_client='"+id_client+"' ORDER BY date", function(err, rows) {
cnt--;
if (typeof rows !== 'undefined') messages[id_client]=rows;
if(!cnt) done();
});
答案 2 :(得分:0)
我认为你在console.log()
之后map
。但是地图还没有完成,因为它的回调是异步的。
您可以使用async获取map
的asynchnous版本,它将起作用:
'use strict';
let async = require('async'),
messages = {};
async.map(Object.keys(clients), (id_client) => {
mysql.query("SELECT * FROM messages WHERE id_client='"+id_client+"' ORDER BY date", (error, rows) => {
if (typeof rows !== 'undefined') {
messages[id_client]=rows;
}
callback(error);
});
}, (error) => {
if(error) {
console.log(error);
}
console.log(messages);
});