代码
// Generated by CoffeeScript 1.4.0
var a, f, log;
a = 1;
log = console.log;
f = function(b) {
log(b);
return process.nextTick(function() {
return f(b + 1);
});
};
f(a);
居然就这么执行了.. 不是说 JS 没有尾递归优化的么,
而且作用域里的 b 不是也要保存的么... 可是没有栈溢出的报错
回复 (9)
A
如果不用process.nextTick,为什么递归次数会出现以下结果:
1.如果是保存为文件,运行:永远是在17956次的时候停止?
2.如果是在node-shell里运行:则递归次数不固定,但会停止!
J
引用 a272121742如果不用process.nextTick,为什么递归次数会出现以下结果: 1.如果是保存为文件,运行:永远是在17956次的时候停止? 2.如果是在node shell里运行:则递归次数不固定...
我是文件 17927..
coffee 的 Shell 是 20902..
在 node 里在这附近变动 20893 20888 20886 20883..
v0.8.16
J
网上搜出来, 貌似和栈的深度有对应.. 没测试 https://groups.google.com/forum/?fromgroups=#!topic/nodejs-dev/KyBoGTAq1cQ
$ node --stack_size=2048
> var err, n=0; (function f(){ n++; try {f()} catch (e) {err=e}})(), [err.message, n]
[ 'Maximum call stack size exceeded', 21809 ]
$ node --stack_size=4096
> var err, n=0; (function f(){ n++; try {f()} catch (e) {err=e}})(), [err.message, n]
[ 'Maximum call stack size exceeded', 43654 ]
$ node --stack_size=8192
> var err, n=0; (function f(){ n++; try {f()} catch (e) {err=e}})(), [err.message, n]
Segmentation fault ( oops :-)
J
这玩意不算真正的递归调用吧。执行一次,将内容压入任务队列中,下次循环的时候取出来执行,然后重复。并不是在一次循环中完成的。
J
引用 JacksonTian这玩意不算真正的递归调用吧。执行一次,将内容压入任务队列中,下次循环的时候取出来执行,然后重复。并不是在一次循环中完成的。
就是说递归是不会压入队列了.. 那除此之外还有区别么, 比如压入队列的环境的内容, 是跟直接递归时一样的?
C
每次nexttick调用的匿名函数是新定义的,它在转调用的f,也就是你的f通过一个匿名函数调用f,中间间隔了一层,就不是递归调用了
J
引用 codekiller每次nexttick调用的匿名函数是新定义的,它在转调用的f,也就是你的f通过一个匿名函数调用f,中间间隔了一层,就不是递归调用了
意思能懂, 但让我自己区分还真是区分不出来了..
process.nextTick 到底做了什么...
C
这不是递归调用 你只是递归定义新函数而已
J
引用 codekiller这不是递归调用 你只是递归定义新函数而已
后续的 f 不是原先定义的那个 f 继续执行?
参与回复
登录后即可参与回复。登录