JavaScriptfor循环中的setTimeout不打印连续值
我有这个脚本:
for (var i = 1; i <= 2; i++) { setTimeout(function() { alert(i) }, 100);
}
但3
被警告两次,而不是1
那么2
。
有没有一种方法可以传递i
而不将函数编写为字符串?
回答:
您必须为每个超时功能安排一个单独的“ i”副本。
function doSetTimeout(i) { setTimeout(function() { alert(i); }, 100);
}
for (var i = 1; i <= 2; ++i)
doSetTimeout(i);
如果您不做这样的事情(同一想法还有其他变体),那么每个计时器处理程序函数将 相同的变量“ i”。循环结束后,“
i”的值是多少?3!通过使用中间函数,将 变量的值。由于超时处理程序是在该副本的上下文中创建的,因此它具有自己的专用“ i”。
编辑 -随着时间的流逝,出现了一些评论,由于设置了一些超时会导致处理程序同时执行所有操作,因此有些混乱显而易见。重要的是要了解, 设置
计时器的过程-
调用setTimeout()
-几乎不需要时间。也就是说,告诉系统“请在1000毫秒后调用此函数”将几乎立即返回,因为在计时器队列中安装超时请求的过程非常快。
因此,如果进行了 一系列
超时请求(如OP中的代码和我的答案中的情况),并且每个时间延迟值都相同,那么一旦经过该时间量,所有计时器处理程序会迅速相继被称为。
如果您需要按间隔调用处理程序,则可以使用setInterval()
,它的调用方式与完全相同,setTimeout()
但是在重复请求数量的延迟后将触发多次,或者您可以建立超时并乘以时间您的迭代计数器的价值。也就是说,修改我的示例代码:
function doScaledTimeout(i) { setTimeout(function() {
alert(i);
}, i * 5000);
}
(在100
毫秒级的时间内,效果不会很明显,因此我将该数字提高到5000。)将的值i
乘以基本延迟值,因此在循环中调用5次将导致5次延迟。秒,10秒,15秒,20秒和25秒。
在2018年,这里有一个更简单的选择。由于具有在比函数更狭窄的范围内声明变量的新功能,因此,如果修改了原始代码,则可以工作:
for (let i = 1; i <= 2; i++) { setTimeout(function() { alert(i) }, 100);
}
与let
声明不同var
,声明本身会导致i
循环的每次迭代都具有不同的内容。
以上是 JavaScriptfor循环中的setTimeout不打印连续值 的全部内容, 来源链接: utcz.com/qa/404408.html