`process.nextTick` 如何防止我的堆栈爆炸? [英] How does `process.nextTick` keep my stack from blowing up?

查看:41
本文介绍了`process.nextTick` 如何防止我的堆栈爆炸?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我偶然发现了一个写入文件的函数(这里是 SO),但确保不会覆盖一个文件:

I've stubled upon a function (here on SO) which writes a file, but makes sure to not overwrite a file:

function writeFile(i){
    var i = i || 0;
    var fileName = 'a_' + i + '.jpg';
    fs.exists(fileName, function (exists) {
        if(exists){
            writeFile(++i);
        } else {
            fs.writeFile(fileName);
        }
    });
}

现在下面有一条有趣的评论说:

Now there is an interesting comment below which says:

小调整:由于 JavaScript 不会优化尾递归,请将 writefile(++i) 更改为 process.nextTick(function(i) {writefile(++i);}); 如果您必须处理大量文件名,这将防止您的堆栈爆炸.

Minor tweak: Since JavaScript doesn't optimize tail recursion away, change writefile(++i) to process.nextTick(function(i) {writefile(++i);}); that will keep your stack from blowing up if you have to go through lots of file names.

请解释.process.nextTick 如何防止栈炸毁?

Please explain. How does process.nextTick prevent the stack from blowing up?

更新:原来评论中的假设是错误的!无论如何,确实存在 process.nextTick 在防止堆栈溢出方面发挥作用的情况(请参阅已接受答案中的示例).

Update: Turns out the assumption in the comment was wrong! Anyway, cases do exist where process.nextTick plays a role in preventing a stack overflow (see examples in accepted answer).

推荐答案

如果您有一个同步调用自身的函数,例如 200k 次,由于堆栈嵌套太深,代码将错误退出.process.nextTick 避免了类似于 setTimeout(fn,0) 在每次迭代时清除调用堆栈的方式.它只是将传递的函数的执行推迟到下一次 eventloop 运行.

If you had a function that called itself synchronously, say, 200k times, the code will exit with error due to the stack being too deeply nested. process.nextTick avoids that similar to the way setTimeout(fn,0) will by clearing the callstack on each iteration. It simply defers the execution of the passed function until the next time the eventloop runs.

更多阅读(但已过时):http://howtonode.org/understanding-process-下一个勾

More reading (but out of date): http://howtonode.org/understanding-process-next-tick

会落入此陷阱的示例函数:

Example function that would fall into this trap:

(function doWork (i) {
    if (i === 0) return;
    console.log('Doing work!');
    doWork(--i);
}(2000000))

和 process.nextTick 修复了相同的功能:

and the same function fixed with process.nextTick:

(function doWork (i) {
  if (i === 0) return;
  console.log('Doing work!');
  process.nextTick(function () {
    doWork(--i);
  });
}(2000000))

<小时>

但是,在您的情况下,这不会成为问题,因为由于 fs.exists(,代码是异步的,因此您所指的注释不正确.


However, in your case this won't be a problem because the code is asynchronous due to fs.exists(, therefore the comment you were referring to is incorrect.

这篇关于`process.nextTick` 如何防止我的堆栈爆炸?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆