为了账号安全,请及时绑定邮箱和手机立即绑定

为什么 let 在 async for 循环中工作而 var 没有?

为什么 let 在 async for 循环中工作而 var 没有?

缥缈止盈 2021-08-20 18:08:56
我很难理解为什么let在 JavaScript 中使用异步 for 循环。我正在使用异步函数从数据库中进行各种插入和检索我的代码看起来像这样:for (var i = 0; i < row.length; i++) {   pool.query(`Select Name from Students where ID = ${row[i].PartID}`)                .then(rows => {                    ....                    ....}数组从最大值i而不是 0 开始row[i]。我明白我做错了什么,但是当我寻找解决方案时,我发现使用let而不是var i解决问题。然而,我不明白为什么会这样。为什么 using在异步函数执行之前let停止变量i增加?
查看完整描述

2 回答

?
手掌心

TA贡献1942条经验 获得超3个赞

var 有函数作用域。


let 具有块作用域。


所以,在这样的for循环中:


for (let i = 0; i < row.length; i++) 

循环的每次迭代都有它自己的单独i变量。当在循环内使用异步操作时,每个单独的i变量都有自己的异步回调,因此一个不会覆盖另一个。


由于var是函数作用域,当你这样做时:


for (var i = 0; i < row.length; i++) 

i整个函数中只有一个变量,for循环的每次迭代都使用相同的变量。for循环的第二次迭代改变i了第一次迭代中任何异步操作可能试图使用的值。如果这些异步操作试图i在异步回调中使用它们的值,这for可能会给这些异步操作带来问题,因为同时循环已经改变了它。


这是一个经典的例子:


for (var i = 0; i < 5; i++) {

    setTimeout(function() {

        console.log(i);

    }, 10);

}

而且,现在与 let


for (let i = 0; i < 5; i++) {

    setTimeout(function() {

        console.log(i);

    }, 10);

}

运行每一个并查看结果的差异。在这两个示例中,for循环运行到完成并安排了 5 个计时器。在这个var例子中,所有的计时器回调都看到了i现在完成的for循环中的一个变量,因此它们都输出5为 的值i。


在这个let例子中,循环的每次迭代都有它自己的i变量,它不受for循环行进的影响,所以当他们的定时器回调被调用时(for循环完成后),它们仍然具有与i迭代时相同的值的for循环最初执行的,因此它们的输出越来越多的预期序列。


查看完整回答
反对 回复 2021-08-20
?
慕田峪7331174

TA贡献1828条经验 获得超13个赞

我要看的一件事是 for 循环的每次迭代是否正在等待您的异步函数解析。在您连接到数据库并执行操作期间,它可能会继续运行。这就是为什么它从 max 开始。

除此之外,尚不清楚为什么即使使用此处显示的新块范围规则,使用“let”也会很重要


查看完整回答
反对 回复 2021-08-20
  • 2 回答
  • 0 关注
  • 196 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信