await没有返回

发布于 2022-09-07 12:23:46 字数 208 浏览 20 评论 0

let p = new Promise(resolve => {})

const noReturn = async function() {
  const res = await p()
  return res
}

某处多次调用noReturn方法,会不会有什么不好的影响?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

倾听心声的旋律 2022-09-14 12:23:46

p到底是Promise,还是是函数?如果pPromise,会有不好的影响,否则不会。

当前V8的Promise的实现,会在满足以下条件的时候回收掉所有.then链的上下文

  1. resolve没人要了
  2. reject也没人要了
  3. !!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它们保持一致。

篱下浅笙歌 2022-09-14 12:23:46

会,从代码看(我觉得是示例代码没写好的原因吧),大量的promise处于pending状态,一是gc没法回收,二是event loop每个阶段之间都要检查promise

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文