提问人:Shambo Basu 提问时间:6/12/2021 更新时间:6/12/2021 访问量:52
在 setTimeout 内部循环中保留参数值
Preserve parameter value in setTimeout inside loop
问:
我正在学习 setTimeout,并尝试在循环中打印一个有延迟的数组,每次迭代后,不同索引处的值都会发生变化。我的原始数组是 [1,2,3,4,5]。我希望输出是这样的:
我知道闭包可以与 setTimeout 一起使用,以保留参数的值,直到执行,就像这些 Stack Overflow 问题中提到的一样。如何在执行前保留setTimeout参数值?并且 for 循环中的 setTimeout 不打印连续值
所以它试了这个
let a = [1,2,3,4,5];
for(let i=0;i<a.length;i++){
a[i]=7;
dotimeout(a,i)
}
function dotimeout(a,i){
setTimeout(function(){
console.log(a)},i*1000)
}
和
let a = [1,2,3,4,5];
for(let i=0;i<a.length;i++){
a[i] = 7;
(
function(b,j){
setTimeout(()=>{
console.log(b);
},j*1000)
}(a,i)
);
}
但两者都给了我相同的结果:
我知道可以在 setTimeout 回调中完成数组操作以达到预期的结果,但这不是我的查询
所以我的问题是:为什么包装 setTimeout( closures,不确定这是否是正确的术语)的函数不起作用,以及如何保留 setTimeout 参数,直到使用 setTimeout 外部的数组操作执行。
答:
您的循环从头到尾运行。在每次迭代中,它都会将 的元素之一设置为 ,并安排稍后的回调,使用 。a
7
setTimeout
当回调开始调用时 - 的所有元素都已设置为 。a
7
当你作为一个变量传递给你的内部函数时,你实际上传递了一个对它的引用,所以在里面,你的函数仍然可以看到最新的数组。a
a
您可以做的一件事是复制并传递:a
let a = [1,2,3,4,5];
for(let i=0;i<a.length;i++){
a[i] = 7;
let copyOfA = [ ...a ];
(
function(b,j){
setTimeout(()=>{
console.log(b);
},j*1000)
}(copyOfA,i)
);
}
虽然使用副本,但内部功能是多余的。这也将起作用:
let a = [1,2,3,4,5];
for(let i=0;i<a.length;i++){
a[i] = 7;
let copyOfA = [ ...a ];
setTimeout(()=>{
console.log(copyOfA);
},i*1000)
}
代码没有做错任何错误。解决方案非常简单,只需放入代码块即可。Javascript 有一个叫做 stack 的东西,setTimeout 功能块中的任何事件总是在调用该 setTimeout 的函数的每个事件之后触发,即使超时为 0ms。因此,在进入下一个循环之前,您不会等待任何毫秒的 setTimeout 完成,实际上它只是这样做,然后调用将分配给调用堆栈底部的 which。a[i] = 7
setTimeout
a[i] = 7
dotimeout
评论