• 全部
  • 问答

setTimeout 为什么不会堆栈溢出?

lovetysx 2012-09-03 10:56:27
假如代码如下

function callback(f) {
f();
}

function foo() {
foo(); //执行1000次左右会发生堆栈溢出的错误,
//setTimeout(foo, 0); //永远不会堆栈溢出
}
foo()

这是什么原理?
请问假如我自己把callback函数也定义成setTimeout这样的,应该怎么写?
...全文
262 点赞 收藏 11
写回复
11 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
yibey 2012-09-05
http://blog.csdn.net/yibey/article/details/7946101

它不是多线程的,那只是一种理解方式了,需要详细了解的话看上面的文章吧
回复
泡泡鱼_ 2012-09-04
我发现CSDN真是抽抽了。老是说发了,就是看不见
回复
未知数 2012-09-04
分挺多的我就再补充下:
如果你不能理解异步是怎么回事,
function foo() {
foo(); //
alert(); //这种递归调用永远都不会执行到这一步,因为上一步永远结束
}
foo()


function foo() {
setTimeout(foo, 0); //
alert();//这个能够被执行弹出,因为递归调用的函数抛给setTimeout处理了,就算不能结束也与当前函数无关了,当前函数会继续执行
}
foo()


回复
未知数 2012-09-04
分挺多的我就再补充下:
如果你不能理解异步是怎么回事,
function foo() {
foo(); //
alert(); //这种递归调用永远都不会执行到这一步,因为上一步永远结束
}
foo()


function foo() {
setTimeout(foo, 0); //
alert();//这个能够被执行弹出,因为递归调用的函数抛给setTimeout处理了,就算不能结束也与当前函数无关了,当前函数会继续执行
}
foo()


回复
泡泡鱼_ 2012-09-04
LZ这个,有个通俗点的说法,叫死循环呢吧
回复
licip 2012-09-04
楼上已有答案了。
回复
hch126163 2012-09-04
死循环了。
settimeout 每次执行是有停顿的,至少30ms
回复
yibey 2012-09-04
function foo() {
foo();

}
foo()

此处是无限递归,对于每一次的递归都回进行入栈操作,因为是无限递归,就不断的入栈,直到栈溢出为止(大约2M的容量吧)。
而settimeout调用foo
只是无限循环而已就是说
执行foo的时候入栈,
然后执行settimeout函数这个时候虽然它又继续调用自己,但是这里可以理解多线程操作了,只是开启另一个线程来启动foo,而当前线程仍然继续执行,当当前线程的foo执行完成后,自然就出栈了,每一次的FOO执行都是这个过程,所以栈里不会容量超标的
回复
fatlism 2012-09-04
回复
lovetysx 2012-09-04
[Quote=引用 7 楼 的回复:]

function foo() {
foo();

}
foo()

此处是无限递归,对于每一次的递归都回进行入栈操作,因为是无限递归,就不断的入栈,直到栈溢出为止(大约2M的容量吧)。
而settimeout调用foo
只是无限循环而已就是说
执行foo的时候入栈,
然后执行settimeout函数这个时候虽然它又继续调用自己,但是这里可以理解多线程操作了,只……
[/Quote]

如果是多线程的,为什么当前线程的上下文都可以访问到呢?
回复
未知数 2012-09-03
setTimeout 是伪异步执行的,你把函数交给setTimeout处理后,原来的函数不会等待,会继续执行,函数能够结束,资源也就可以释放
而不用setTimeout的时候,函数必须等待调用的函数返回后才能继续执行,但调用的函数又必须等待下一极函数......这样所有函数都不能结束,资源就一直不释放,故溢出



function callback(f) {
f();
setTimeout(function(){callback(f)},0);
}
回复
发帖
JavaScript
创建于2007-09-28

8.5w+

社区成员

Web 开发 JavaScript
申请成为版主
帖子事件
创建了帖子
2012-09-03 10:56
社区公告
暂无公告