考虑这个片段:
function f() {
return new Promise((resolve, reject) => {
f().then(() => {
resolve();
});
});
}
f();
也可以这样写:
async function f() {
return await f();
}
f();
如果您运行给定的两个代码中的任何一个,您将遇到此错误:
(node:23197) UnhandledPromiseRejectionWarning: RangeError: Maximum call stack size exceeded
我的问题是为什么?在回答我的问题之前,请考虑我的论点:
我了解递归的概念以及如果没有停止条件它如何导致堆栈溢出。但我在这里的论点是,一旦第一个 f();
被执行,它将返回一个 Promise
并且它退出堆栈,所以这个递归不应该面临任何堆栈溢出.对我来说,这应该与以下行为相同:
while (1) {}
当然,如果我这样写,就搞定了:
function f() {
return new Promise((resolve, reject) => {
setTimeout(() => {
f().then(() => {
resolve();
});
}, 0);
});
}
f();
这是一个不同的故事,我没有问题。
[更新]
糟糕,我忘了说我正在服务器端使用 node v8.10.0
进行测试。
最佳答案
为什么你不认为它会导致无限递归? promise 的构造函数递归调用 f,因此 promise 永远不会构造,因为在构造 promise 之前会发生无限递归循环。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
来自上面的链接
执行器函数由 Promise 实现立即执行,传递 resolve 和 reject 函数(执行器在 Promise 构造函数甚至返回创建的对象之前被调用)。
关于javascript - 为什么 Javascript 中的递归异步函数会导致堆栈溢出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56879005/