如何将变量传递到 setTimeout 函数中
How to pass a variable into a setTimeout function?
我正在尝试设置五个交错的函数调用(相隔一秒)。这部分工作正常。不起作用的是,我无法将值 0 到 4 传递到回调函数中。它每次只通过"5"。我似乎无法弄清楚为什么以及如何解决它。
法典:
function callback(num)
{
console.log(num);
}
for (var i = 0, loadDelay = 1000; i < 5; ++ i, loadDelay += 1000)
setTimeout(function() { callback(i); }, loadDelay);
结果:
5
5
5
5
5
期望的结果:
0
1
2
3
4
那是因为你创建了一个闭包。因此,您传递给的函数setTimeout
共享相同的i
实例。在支持标准(不是 IE)的浏览器中,您可以拥有:
setTimeout(callback, loadDelay, i);
看: http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#timers
否则,您必须实际将参数bind
到函数:
setTimeout(callback.bind(undefined, i), loadDelay);
看: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
如果浏览器不支持 ES5 bind
方法,您可以实现上面链接中存在的填充程序,也可以手动执行以下操作:
setTimeout(function(index){
return function() { callback(index) }
}(i), loadDelay);
但我想说的是,使用 bind
更具可读性,并且值得实现填充程序。你实际上可以使用这个: https://github.com/kriskowal/es5-shim
在浏览器中添加本机不支持 es5 的 es5 功能(如果可能)。
使用 lambda/函数表达式捕获当前值。 例如
for (var i = 0, loadDelay = 1000; i < 5; ++ i, loadDelay += 1000) {
var doCall = function (j) {
setTimeout(function() { callback(j); }, loadDelay);
}
doCall(i);
}
这里的问题是循环的所有迭代只有 1 i
值。 javascript 中的变量具有函数作用域,即使你可以在块内声明它们。 这意味着i
整个函数都处于活动状态。
为了说明问题,请考虑以下代码的执行方式与您的示例完全相同
var i;
for (i = 0, loadDelay = 1000; i < 5; ++ i, loadDelay += 1000) {
...
}
我的解决方案之所以有效,是因为它引入了一个新函数,因此为 j
引入了新的变量生命周期。 这会在函数中保存 i
的当前值,以便在setTimeout
回调中使用
由于变量作用域,您需要一个闭包才能通过i
。查看这篇文章,以及这篇文章,了解有关闭包的一些好信息。
现场演示
function callback(num)
{
console.log(num);
}
for (var i = 0, loadDelay = 1000; i < 5; ++ i, loadDelay += 1000)
setTimeout((function(num){return function(){
callback(num);
}
})(i), loadDelay);
setTimeout会产生一些奇怪的范围问题。Frame.js旨在解决一些此类混淆,这也适用于[更新]:
function callback(num) {
console.log(num);
}
for (var i = 0, loadDelay = 1000; i < 5; ++ i, loadDelay += 1000) {
Frame(function(next, i){
setTimeout(function() { callback(i); }, loadDelay);
next();
}, i);
}
Frame.init();
- setTimeout函数能否在其前面的代码执行之前激发
- JS:setTimeout函数的UI计数
- Jasmine:测试setTimeout函数会抛出一个错误
- Javascript/Jquery setTimeout 函数不适用于长 html
- 如何让 setTimeout 函数运行,然后停止使用循环
- 有没有办法覆盖 setTimeout 函数,使其使用微秒而不是毫秒
- setTimeout函数的精确计时
- Javascript-为什么不是't此setTimeout函数正在工作
- 阻止页面重新加载时的setTimeout函数
- 2 setTimeout函数第一个清除第二个javascript
- 如何在 setInterval/setTimeout 函数中按名称调用函数
- Javascript SetTimeOut函数不知怎么不起作用
- Javascript setTimeOut 函数与 .net 中 Windows 应用程序的计时器不匹配
- Javascript setTimeout 函数保持运行
- 当 ajax 返回 1 时如何删除 setTimeout 函数
- setTimeout 函数比它应该的更快
- Javascript:我的setTimeout函数由于第三方而不起作用
- 如何或在哪里将javascript settimeout函数添加到CSS垂直下拉菜单
- 在 javascript 对象中使用方法的值以在 setTimeout 函数中使用
- 如何阻止此 setTimeout 函数运行