我有两个递归承诺链,它们似乎在做同样的事情,但其中一个导致内存泄漏,而另一个则没有。我已将代码简化为以下示例:
泄露代码:
function leakingLoop() {
return delay(1)
.then(() => {
console.log(`Tick ${Date.now()}`)
return leakingLoop()
})
}
不漏码:
function nonLeakingLoop() {
delay(1)
.then(() => {
console.log(`Tick ${Date.now()}`)
nonLeakingLoop()
})
}
两者之间唯一的区别是,leakingLoop 函数返回延迟承诺的结果,而 nonLeakingLoop 函数则不会。
有人可以解释为什么leakingLoop函数会导致内存泄漏,而nonLeakingLoop函数则不会吗?关于处理承诺的方式有什么我遗漏的吗?
注意:我假设延迟函数是一个基于承诺的函数,会在一定时间后解析。如果情况并非如此,请告诉我,我会相应地更新问题。
我建议你观看 Jake Archibald 对 JS 事件循环的解释。
TL;DR对此解释如下: 事件循环通过维护
Call stack
(函数调用被推送和弹出)和 Task Queue
(异步任务等待执行)来处理操作。
每个leakingLoop调用都会返回一个新的promise,该promise链接到前一个promise,从而导致不断增长的promise链。这种增长仍在继续,防止旧的 Promise 被垃圾收集,进而导致内存泄漏。