在forEach的另一个回调中引用同一个对象

时间:2013-02-08 21:42:25

标签: javascript

我正在尝试向对象添加新属性。它似乎在这个范围内正常工作:

rows.forEach(function (row, i) {
  row.foo = i;
});

如果我执行console.log(行),我可以看到foo添加了正确的值。如果我在forEach中有另一个回调,我不再看到更改了。为什么呢?

rows.forEach(function (row, i) {
  getUserById(row.user_id, function(user) {           
    row.foo = i;
  });
});

是的,回调得到了正确的解雇。这是getUserById

function getUserById(userId, callback) {
  connection.query('select * from t_user where id = ?', [userId], function(err, results) {

  if (err) {
    console.log("repo error");
  } else {
    if (results.length == 0) {
      callback(null);
  } else {
      callback(results[0]);
    }
  }
});

}

1 个答案:

答案 0 :(得分:0)

如果getUserById延迟调用您传递的回调函数,我只能想象您会看到此问题。在这个假设下,你的问题是一个时间问题。

每次调用getUserById并向其传递回调时,您基本上都会说“当您获得此ID的用户时调用此函数”,然后继续执行其余程序。这意味着当调用console.log时,您的回调尚未被调用。相反,您必须等待所有回调完成,然后调用任何依赖于您在回调中设置的值的代码。

等待所有回调完成的一般方法是制作一个特殊的回调函数,该函数将委托给每个回调并且一旦被调用就跟踪它们。

这是一个使用async库的答案的问题,我很喜欢它(虽然有很多库可以解决这个控制流问题)。

Idiomatic way to wait for multiple callbacks in Node.js

这是一个原始的JavaScript解决方案,它足够强大,可以在一般情况下工作,而不是所有的回调都是相同的(也就是说,如果你想为每个用户id提供不同的回调)。

Multiple Asynchronous Callbacks - Using an array to fire function when complete