for循环中的箭头函数闭包

时间:2017-11-16 22:55:24

标签: javascript ecmascript-6

鉴于此:

Browse Other -> Browse Static Calls

如果我在#Simple way to do it def foldStrings(str1, str2): newStr = "" counter = 0 if len(str2) == len(str1): while counter < len(str2): newStr = newStr + str1[counter] + str2[counter] counter += 1 return newStr else: return "The two Strings are not equal in length" 中发出提醒,它将始终输出值var m = 5; for (i = 0; i < m; i++) { add_row('row-'+(i+1), () => f(i)) } 。我相信这是由于python提到的同样的问题:

NtWaitForSingleObject

如何在javascript中解决此问题?

1 个答案:

答案 0 :(得分:0)

这是因为add_row()是异步的。当操作完成时,它会在稍后的某个时间调用您传递的回调。同时,for循环已经完成。 ES6中的一个简单解决方案是将letfor循环一起使用。这为循环的每次运行创建了一个新的独立i变量,所以当某个时候稍后调用回调时,循环调用的变量i仍然是函数启动时的变量console.log()

如果您要在代码中插入一些var m = 3; console.log("A"); for (i = 0; i < m; i++) { console.log("B" + i); add_row('row-'+(i+1), () => { console.log("C" + i); f(i); }) } console.log("D"); 语句,请执行以下操作:

 A
 B0
 B1
 B2
 D
 C0
 C1
 C2

您在控制台中看到的是:

for

注意“D”在任何“Cx”行之前是如何出现的。这向您展示了在let循环执行完毕后如何调用异步回调。

请研究一下,当您完全理解该命令的推理时,您将最终理解异步回调。从技术上讲,C0,C1和C2将在最后,但可以相对于彼此的任何顺序。

以下是如何使用fori循环为循环的每次迭代创建单独的变量i,以便您仍然具有{{1}的适当值稍后调用回调时:

for (let i = 0; i < m; i++) { 
    add_row('row-'+(i+1), () => f(i))
}

在ES6之前,可以通过创建一个额外的闭包来解决这个问题,该闭包创建一个新的函数作用域变量,以便为每次调用分别“记住”循环索引:

for (var i = 0; i < m; i++) { 
    (function(index) {
        add_row('row-'+(index+1), () => f(index))
    })(i);
}