通过for循环中的异步函数设置变量

时间:2016-08-24 12:38:45

标签: javascript node.js

我遇到过一种情况,我在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()包装到带有回调的另一个函数中,以及解决整个异步事件的所有问题。如果在循环内部进行迭代,我只是不知道这一切是如何工作的。

3 个答案:

答案 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);
});