【问题标题】:Javascript (NodeJS) Callback ScopeJavascript (NodeJS) 回调范围
【发布时间】:2014-11-09 05:56:54
【问题描述】:

如何从回调中访问父作用域。回调是函数 (err, obj)。 var to_user_id 在所有迭代中都是相同的。看起来回调是在所有迭代完成后处理的,因此 var to_user_id 只是所有回调的一个值。

for(var i = 0, len = keys.length; i < len; i++) {

  to_user_id = keys[i].replace('m', '')

  client.get(keys[i], function (err, obj) {
    //var not updating, why is both to_user_id=77
    console.log("match: to_user_id=" + to_user_id + " from_user_id=" + obj)
    var match = "match: to_user_id=" + to_user_id + " from_user_id=" + obj
    io.emit(1, match);
  });

}

输出

查看两次迭代的 to_user_id 如何为 77。一个应该是 6,最后一个应该是 77。

匹配:to_user_id=77 from_user_id=77

匹配:to_user_id=77 from_user_id=6

client.get 是一个 redis 函数,以防万一。

【问题讨论】:

    标签: javascript node.js redis


    【解决方案1】:

    您的client.get() 调用是异步的。因此,for 循环在任何client.get() 回调执行之前完成。这意味着to_user_id 将在第一个client.get() 回调被执行时设置为keys[keys.length - 1].replace('m', '')。这就是为什么您在输出中看到相同的 to_user_id 的原因。

    这里的解决方法是使用闭包来捕获to_user_id 的当前值。最简单的方法是使用keys.forEach()

    keys.forEach(function(key) {
      to_user_id = key.replace('m', '')
    
      client.get(key, function (err, obj) {
        console.log("match: to_user_id=" + to_user_id + " from_user_id=" + obj)
        var match = "match: to_user_id=" + to_user_id + " from_user_id=" + obj
        io.emit(1, match);
      });
    });
    

    【讨论】:

    • 啊。闭包在 forEach 内部创建。
    • 我最终使用了您的代码,因为我无法抗拒它的简洁性。 Javascript 几乎和 Ruby 一样漂亮。
    【解决方案2】:

    你必须创建闭包来保存i变量的值。

    for (var i = 0, len = 5; i < len; i++) {
      (function(i, to_user_id) {
        client.get(i, function(err, obj) {
          io.emit("match: to_user_id=" + to_user_id + " from_user_id=" + obj)
        });
      }(i, keys[i].replace('m', '')));
    }
    

    【讨论】:

    • 太棒了。你是个 JS 天才。
    猜你喜欢
    • 1970-01-01
    • 2013-12-22
    • 1970-01-01
    • 2010-09-16
    • 1970-01-01
    • 1970-01-01
    • 2020-07-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多