反复await永不resolve的Promise会导致内存泄漏吗?
问题:反复使用await处理永不resolve的Promise,会引发内存泄漏吗?
假设存在以下代码:
async function whatHappens() { await neverResolves(); doSomething(); } function neverResolves() { return new Promise(() => {}); } function doSomething() { console.log('never happening'); } // main thread for (/* 非常长的循环 */) { whatHappens(); }
已知无引用的挂起Promise会被垃圾回收,但不确定await是否会被视为“引用”,导致暂停的函数上下文无法被回收,进而引发内存泄漏。
解答
结论:这些挂起的Promise和对应的异步函数执行上下文最终会被垃圾回收,不会造成内存泄漏。
原因如下:
- await的本质是为目标Promise注册回调,但如果没有任何外部代码持有这个Promise(比如示例中每次调用
whatHappens()后,返回的Promise没有被赋值给任何变量,也没有被后续代码引用),那么这个Promise以及它关联的异步函数暂停上下文,都属于不可达对象。 - 现代JavaScript引擎(如V8、SpiderMonkey)的垃圾回收机制会识别这类无引用的挂起Promise:因为没有任何途径能触发它的resolve或reject,也没有外部引用指向它,所以会判定这些对象不再有用,将其回收。
- 只有当你主动持有这些Promise的引用时(比如把每次调用
whatHappens()的结果存入一个全局数组),才会导致内存泄漏——因为此时Promise和关联上下文始终处于可达状态,无法被回收。
内容的提问来源于stack exchange,提问作者Miguel Leon
相关产品推荐
相关产品推荐

