2 回答
TA贡献1810条经验 获得超5个赞
p
到底是Promise
,还是是函数?如果p
是Promise
,会有不好的影响,否则不会。
当前V8的Promise的实现,会在满足以下条件的时候回收掉所有.then
链的上下文:
resolve没人要了
reject也没人要了
!!Promise对象也没人要了
所以以下代码完全没有问题,所有东西都会被正确回收
let collectable = (async () => {
const buf = new Uint8Array(1024 * 1024 * 1024);
for (let i = 0; i < buf.length; i++) buf[i] = i;
await new Promise(() => { });
return buf;
})();
if (typeof gc == 'function') gc();
上面的代码中,1和2满足,因为没有变量存着那个空Promise,所以3也满足,所以async内的所有上下文都被释放,collectable只剩下了空壳Monad,薛定谔的猫早跑掉了。
而这段代码会造成内存泄漏
let deadPromise = new Promise(() => { });
let uncollectable = (async () => {
const buf = new Uint8Array(1024 * 1024 * 1024);
for (let i = 0; i < buf.length; i++) buf[i] = i;
await deadPromise;
return buf;
})();
if (typeof gc == 'function') gc();
上面的代码会造成内存泄漏,只有deadPromise = null之后才能回收。
一点后话,我猜题主也是在想,如果我们没有AbortablePromise,那我们至少能明确标示出一个Promise可以被垃圾回收吧?幸运的是,我们可以,但是要用到上面这样的hack。
不过,现在我们有AbortController了,说明社区已经基本上对AbortablePromise怎么实现有了共识:应该throw出去。这样的话,我们就不应该用这样的hack了,而应该与fetch它们保持一致。
TA贡献1842条经验 获得超12个赞
添加回答
举报