timer = window.setTimeout(function () {
//do something
window.setTimeout(arguments.callee, 1000);
}, 1000);
结果是这些代码运作良好。
但为什么没有导致下面的错误?
超出最大调用堆栈大小
调试时,找到变量范围,不包括先前执行的范围" setTimeout函数"
谁可以解释一下?
最好是文档。
答案 0 :(得分:7)
setTimeout
是异步的(它在执行回调之前返回),并且回调将在新的空堆栈帧上执行。这就是整个目的。
这不是递归调用,需要保留范围(在非tail-call - 优化函数的情况下)。但这也意味着功能变得阻塞,这不是你想要的。
答案 1 :(得分:0)
这是因为Timeout回调没有像你假设的那样存储在堆栈中:队列中等待在自己的堆栈中执行。在您的代码中,队列在前一次执行完成时被填充,因此队列不会增长。
更新:您可以查看规范here,但我正在复制文字:
setTimeout()方法必须运行以下步骤:
让handle成为用户代理定义的大于零的整数 这将标识此次调用设置的超时。
在句柄的活动超时列表中添加一个条目。
在活动超时列表中获取定时任务句柄,然后让 任务就是结果。
获取超时,并将超时作为结果。
如果当前正在运行的任务是由。创建的任务 setTimeout()方法,并且超时小于4,然后增加 超时到4。
返回句柄,然后继续运行此算法 异步。
如果方法上下文是Window对象,请等到Document 与方法上下文相关联已经完全活跃了 进一步超时毫秒(不一定是连续的)。
否则,如果方法上下文是WorkerUtils对象,请等待直到 在没有暂停工作的情况下超时毫秒(不是 必须连续)。
否则,按照规范中描述的那样定义 WindowTimers接口由其他一些对象实现。
- 醇>
等到此算法的任何调用在此之前启动 其超时时间等于或小于此时间已完成。
(可选)等待另一个用户代理定义的时间长度。