【问题标题】:Javascript: value of variable changes before being used in the callbackJavascript:在回调中使用之前更改变量的值
【发布时间】:2013-08-13 07:40:54
【问题描述】:

我在一个模块中有这段代码:

    for (var i = 1; i <= n; i++) {
        when = i * 1000;
        track.execute(true, when); // <-- This line calls the method below
    }

这块在另一个模块中:

this.execute = function(on, when){
    [...]

    var createCallback = function(w){ // <-- Here 'when' should be bound to this function when is called below
        return function(buffers){
            object.doSomething(buffers, w);
        }
    };


    [...] // None of this code modifies when or the callback 'factory'

    this.asyncObj.getBuffer(createCallback(when)); // <-- Binding ?!?
};

问题在于when 的值在每次调用时都会更新,因此回调始终使用最新的 when 值执行,而不是在方法执行时设置的值(这是预期的行为)。

如您所见,我已经尝试过这个问题中描述的 hack:JavaScript closure inside loops – simple practical example,但无法做到。

由于某种原因,上面的回调函数总是获取最新的 when 值。

提前感谢愿意提供帮助的人!

PS:我猜这是因为每次都会设置回调,因此每次都设置了最新的 when 值。但我不确定。

更新:这是一个可以尝试的修补程序......而且它有效! o.ohttp://tinker.io/dee10(这段代码在本地反映了我代码的当前状态。反正和上面一样)。

【问题讨论】:

  • 您的代码看起来不错。什么时候真的是一个数字?
  • 是的,这很奇怪。你有一个显示失败的最小例子吗? (JSFiddle,还是什么?)
  • @bfavaretto 是的,什么时候是一个数字。 :D
  • @skishore 我会尽快创建一个小提琴。你看过PS吗?你认为这可能是原因吗?
  • 正如我之前所说,您发布的代码很好。问题可能与您的 asyncObj 有关。例如,如果 getBuffer 将回调存储为 asyncObj 的属性,您将在每次调用时覆盖回调。

标签: javascript variables asynchronous callback closures


【解决方案1】:

正如您发布的问题的已接受答案中所述,JS 中没有块范围,只有函数范围。您的尝试不起作用,因为您只在“createCallback”函数中返回了一个新函数。每次调用 'execute' 函数时都需要返回一个新函数。

更新 嘿马可,看到你的评论。我无法运行您发送的修补程序,但我将代码复制/粘贴到 jsfiddle 中,它工作正常。在这里试试:http://jsfiddle.net/tKkCh/

您可以看到该函数每次都返回正确的“when”值。这就是你想要的,对吧?至少在小提琴中,当您调用factory(i)() 时,小提琴中的代码正在被评估,b/c js 是一种单线程语言。

也许您可以尝试包含更多其他代码以帮助我们弄清楚发生了什么...您尝试使其在“asyncObj”中异步运行的方式可能存在问题。谢谢,祝你好运。

【讨论】:

  • 我知道只有函数作用域,这就是为什么我试图将 when 绑定到 createCallback 中的 w 参数。并且创建的函数总是一个新函数(你可以在这里尝试tinker.io/09b6b)。我不认为我理解你的意思。
  • 非常感谢您的帮助。最终我改变了整个方法,因为我无法弄清楚。我想在引擎盖下还有其他一些我没有考虑到的东西。无论如何,小提琴和修补匠都工作得很好,所以我不知道该说什么。 :) 我会在不久的将来看看它,但我需要让它尽快工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-24
  • 2018-07-11
  • 2013-03-21
  • 1970-01-01
  • 2016-03-19
  • 1970-01-01
相关资源
最近更新 更多