gpt4 book ai didi

Node.js - 超出最大调用堆栈大小

转载 作者:IT老高 更新时间:2023-10-28 21:50:34 26 4
gpt4 key购买 nike

当我运行我的代码时,Node.js 抛出一个 "RangeError: Maximum call stack size exceeded" 异常,这是由于递归调用过多导致的。我尝试通过 sudo node --stack-size=16000 app 增加 Node.js 堆栈大小,但 Node.js 崩溃且没有任何错误消息。当我在没有 sudo 的情况下再次运行时,Node.js 会打印 'Segmentation fault: 11'。有没有可能在不删除我的递归调用的情况下解决这个问题?

最佳答案

你应该把你的递归函数调用包装成一个

  • setTimeout,
  • setImmediate
  • process.nextTick

函数让 node.js 有机会清除堆栈。如果您不这样做并且有许多没有任何 真正 异步函数调用的循环,或者如果您不等待回调,则您的 RangeError: Maximum call stack size exceeded将是不可避免的

有很多关于“潜在异步循环”的文章。 Here is one .

现在还有一些示例代码:

// ANTI-PATTERN
// THIS WILL CRASH

var condition = false, // potential means "maybe never"
max = 1000000;

function potAsyncLoop( i, resume ) {
if( i < max ) {
if( condition ) {
someAsyncFunc( function( err, result ) {
potAsyncLoop( i+1, callback );
});
} else {
// this will crash after some rounds with
// "stack exceed", because control is never given back
// to the browser
// -> no GC and browser "dead" ... "VERY BAD"
potAsyncLoop( i+1, resume );
}
} else {
resume();
}
}
potAsyncLoop( 0, function() {
// code after the loop
...
});

这是对的:

var condition = false, // potential means "maybe never"
max = 1000000;

function potAsyncLoop( i, resume ) {
if( i < max ) {
if( condition ) {
someAsyncFunc( function( err, result ) {
potAsyncLoop( i+1, callback );
});
} else {
// Now the browser gets the chance to clear the stack
// after every round by getting the control back.
// Afterwards the loop continues
setTimeout( function() {
potAsyncLoop( i+1, resume );
}, 0 );
}
} else {
resume();
}
}
potAsyncLoop( 0, function() {
// code after the loop
...
});

现在您的循环可能会变得太慢,因为我们每轮都会浪费一点时间(一次浏览器往返)。但是您不必在每一轮中都调用 setTimeout。正常情况下是可以的。每 1000 次执行一次。但这可能会因您的堆栈大小而异:

var condition = false, // potential means "maybe never"
max = 1000000;

function potAsyncLoop( i, resume ) {
if( i < max ) {
if( condition ) {
someAsyncFunc( function( err, result ) {
potAsyncLoop( i+1, callback );
});
} else {
if( i % 1000 === 0 ) {
setTimeout( function() {
potAsyncLoop( i+1, resume );
}, 0 );
} else {
potAsyncLoop( i+1, resume );
}
}
} else {
resume();
}
}
potAsyncLoop( 0, function() {
// code after the loop
...
});

关于Node.js - 超出最大调用堆栈大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20936486/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com