gpt4 book ai didi

javascript - 具有异步调用的循环内的可变范围

转载 作者:行者123 更新时间:2023-12-05 02:07:15 25 4
gpt4 key购买 nike

我正在循环内使用 socket.io 进行异步调用 ( https://github.com/socketio/socket.io-redis#redisadapterclientsroomsarray-fnfunction )。

elements.forEach((element) => {
const foo = {
id: element.id,
name: element.name,
};

// async code
io.in(element.id).clients((err, clients) => {
foo.clients = clients;
});
});

由于此循环将在所有异步调用完成之前运行完成,是否可以保证回调函数将使用紧接其之前声明的 const foo

最佳答案

is there a guarantee that callback function will use the const foo declared immediately before it

TL; DR; 是的。

socket.io 的引用是无关紧要的。保证来自 JS 本身。


每次

const foo = { ... }

(err, clients) => { foo.clients = clients })

执行它们不是简单地声明一个变量和一个函数,而是创建一个新变量和一个新闭包

您的恐惧可能来自 var 的常见陷阱:

for(var i = 0 ; i != 3 ; ++i) setTimeout(() => console.log("i =", i), 0)

这将输出 "i = 3" 树次。

但以下任何一项都会给您带来预期的结果:

  1. let/const:

    for(let i = 0 ; i != 3 ; ++i) setTimeout(() => console.log("i =", i), 0)

    那是因为 let(和 const)的行为不同于 var。参见 MDN :

    let allows you to declare variables that are limited to the scope of a block statement, or expression on which it is used, unlike the var keyword, which defines a variable globally, or locally to an entire function regardless of block scope

  2. forEach:

    [1,2,3].forEach((v, i) => setTimeout(() => console.log("i =", i), 0) )

    因为forEach回调的each调用的参数其实是不同的变量

  3. 甚至 var 在一个函数范围内:

    [1,2,3].forEach((v, i_) => { var i = i_; setTimeout(() => console.log("i =", i), 0) } )

    那是因为 var i = i_forEach 回调的 each 声明了一个局部的新变量。

    但在这种情况下并非如此:

    for(let i_ = 0 ; i_ != 3 ; ++i_) {
    var i = i_
    setTimeout(() => console.log("i =", i), 0)
    }

    因为 var提升。所以前面的代码等同于

    var i
    for(let i_ = 0 ; i_ != 3 ; ++i_) {
    i = i_
    setTimeout(() => console.log("i =", i), 0)
    }

关于javascript - 具有异步调用的循环内的可变范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61966858/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com