setTimeout() 如何在 JS 上工作
How is setTimeout() working on JS
Just Learn JS.在我看来,函数 setTimeout 代码区域应该像正常一样工作,但事实并非如此:
var result = 0;
(function (i){
if(i > 0){
result = result + i;
i = i - 1;
setTimeout("arguments.callee(" + i + ")",100);//arguments.callee(i);
}
else if(i == 0)
return;
}(10));
alert(result);
我希望它提醒 55 而不是 10,如果删除设置超时,它会很好。有人知道为什么吗?
尝试
var result = 0;
(function (i, callback) {
if (i > 0) {
result = result + i;
i = i - 1;
var callee = arguments.callee;
setTimeout(function () {
callee(i, callback)
}, 100);
} else if (i == 0) {
callback();
}
}(10, function () {
alert(result);
}));
演示:小提琴
为什么?
您的方法存在多个问题
- setTimeout 是异步的,这意味着您的警报将在添加操作完成之前触发 - 解决方案是使用回调方法,该方法将在添加结束后执行,如上所示
- 当您将字符串传递给
setTimeout
它将在全局范围内执行时,即arguments.callee
将引用与您期望的不同对象。
因为setTimeout
是异步的,简单来说,这意味着它计划稍后执行。JS不会等待它(不会在该行停止代码),而是运行后续代码。
因此,当您稍后设置它时,代码会继续超出"超时循环"并进入警报。在此期间,循环只做了一个周期,result
只增加了 10 个。
您可以执行的操作:
- 您可以在"超时循环"结束时设置警报
- 或者,您可以发送一个函数,即在循环完成后执行的"回调"。
-
arguments.callee
已弃用。您可以命名您的 IIFE 并让超时调用它
鉴于:
- arguments.callee 不受欢迎(并且不推荐使用)
- 命名函数表达式有其自身的问题
- 这里似乎有一个目标,即不创建全局变量来运行超时
考虑在 IIFE 中声明函数(根据我认为您想要的内容进行调整 - 10 次迭代后显示结果为 10 的警报):
var result = 0;
(function (i){
function foo(j) {
if(j > 0){
++result;
setTimeout(function(){foo(--j)},100);
} else {
alert('Result: ' + result);
}
}
foo(i);
}(10));
请注意,不需要 else 块(除非您想返回 undefined
以外的内容)。
哦,请注意,在 ES5 和其他支持它的浏览器(不是 IE <9)中,您可以在调用 setTimeout 时传递参数:
setTimeout(foo, 100, --j);
因此,您保存了一个额外的函数对象。
相关文章:
- 如何使用多个jquery版本,以便Responsive Slides.js工作
- 无法使FlowType.js工作
- Intellisense没有;t在VS2013中为JS工作
- 有人能解释一下如何#ifeq吗/section键使用handle.js工作
- 使dropzone.js工作的傻瓜指南
- 如何获得侧边栏.js工作
- 如何在没有 Web 服务器的情况下做出响应.js工作
- 创建JS工作,但不显示工具栏
- 无法获得简单的敏捷.js工作
- 通过有错误的 Ajax-Request 打印出 HTML 会阻止进一步的 JS 工作
- Angular JS-工作函数中的“错误:[$interpole:interr]Can't interpole:
- 推特's Bootstrap Popover:赢得't工作,即使其他JS工作正常
- 可以'不要让typeahead.js工作
- 无法让Quicksand.js工作
- 通过Grunt使用Node.js工作SASS预处理器
- 可以'不要让popcorn.js工作
- 不能让Bootstrap modal.js工作
- 我怎么能与wordpress中的wow.min.js工作
- 无法让haxe-pixi.js工作-我得到一个空白的白色屏幕
- 不能让impress.js工作