【问题标题】:Node.js: trouble with asynchronous code + js closuresNode.js:异步代码 + js 闭包的问题
【发布时间】:2013-11-27 21:36:13
【问题描述】:

我无法适应 Node 的单线程 + 异步特性以及 javascript 的函数闭包。

假设我有类似的东西:

function foo(bar) {
    someAsyncFunction(function callback(err) {
        // do stuff with 'bar'
    });
}

如果我遗漏了什么,请告诉我;但我的理解是:

  • 由于关闭,callback 将有一个 referencebar
  • 但是,如果 foo 被调用一次,bar = 20,那么再次使用 bar = 42 之前 callback 在第一次调用时被调用,那么bar 将是callback 中的 42,这是由第一次调用 foo 产生的。在 换句话说:

    1. foo(20)#1
    2. someAsyncFunction(function callback() {})#1
    3. foo(42)#2
    4. someAsyncFunction(function callback() {})#2
    5. callback() #1 --------> 使用 bar=42
    6. callback() #2 --------> 使用 bar=42

我说得对吗? (bar 是原始的还是对象有关系吗?)。如果是这样,我该怎么做才能确保callback 使用正确的bar 值(除了将bar 一直向下和向上传递调用堆栈)?感谢您的帮助。

【问题讨论】:

    标签: javascript node.js asynchronous closures


    【解决方案1】:

    这是不正确的。每次调用foo 都会创建一个新的bar,因此每个回调函数都可以访问不同的bar

    如果您希望只有一个bar,请在foo 之外声明它,以便foo 的每次调用共享相同的bar

    var bar;
    function foo(arg) {
        bar = arg;
        someAsyncFunction(function callback(err) {
            // do stuff with 'bar'
        });
    }
    

    这里,foo 没有声明一个新的bar 变量,而是将bar 的值设置在更高的范围内。

    【讨论】:

    • '每次调用 foo 都会创建一个新栏'——这就是困扰我的地方。确实,您发布的示例正是我所想的。感谢您的回复!
    【解决方案2】:

    不,bar 在执行第一个异步回调时仍为 20。对foo 的每次调用都会获得自己的bar,这不会受到未来对foo 的调用的影响。

    【讨论】:

    • 感谢您的回复。确实你是对的,但我决定接受另一个答案,因为他提供的例子让我更容易看到范围界定问题。不过谢谢!
    猜你喜欢
    • 2022-01-22
    • 1970-01-01
    • 2023-03-04
    • 2013-03-25
    • 2015-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-26
    相关资源
    最近更新 更多