等待但从未解决/拒绝的承诺内存使用情况 [英] Awaited but never resolved/rejected promise memory usage

查看:57
本文介绍了等待但从未解决/拒绝的承诺内存使用情况的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

await使用既不解决也不拒绝(从未解决/未实现)的Promise会导致内存泄漏吗?

Will awaiting a Promise which neither resolves nor rejects (never settle/unfulfilled) cause a memory leak?

当我用 slorber/awesome-debounce-查看React钩子时,我对此感到很好奇诺言会创建新的诺言,但只会结清最后一个诺言,从而使许多/大多数人感到不安/未兑现.

I got curious about this while looking at React hooks with slorber/awesome-debounce-promise that creates new promises, but only settles the last one of them, thus leaving many/most unsettle/unfulfilled.

推荐答案

序言(您可能知道!):

Preface (you probably know this!):

await是用于使用promise回调的语法糖. (真的,真的,真的很好糖.) async函数是JavaScript引擎为您构建承诺链等的函数.

await is syntactic sugar for using promise callbacks. (Really, really, really good sugar.) An async function is a function where the JavaScript engine builds the promise chains and such for you.

答案:

相关的问题不关乎是否兑现了诺言,而是诺言回调(以及它们引用/关闭的内容)是否保留在内存中.当promise在内存中并且尚未解决时,它会引用其回调函数,将其保留在内存中.有两点使这些引用消失了:

The relevant thing isn't so much whether the promise is settled, but whether the promise callbacks (and the things they refer to / close over) are retained in memory. While the promise is in memory and unsettled, it has a reference to its callback functions, keeping them in memory. Two things make those references go away:

  1. 履行诺言,或者
  2. 释放对承诺的所有引用,使其有资格获得GC(可能在下文中有更多说明)

在通常情况下,promise的使用者将处理程序挂接到该promise,然后要么根本不保留对它的引用,要么仅在处理程序功能关闭且上下文中保留对它的引用.没有其他地方. (而不是例如,将promise引用保留在长期存在的对象属性中.)

In the normal case, the consumer of a promise hooks up handlers to the promise and then either doesn't keep a reference to it at all, or only keeps a reference to it in a context that the handler functions close over and not elsewhere. (Rather than, for instance, keeping the promise reference in a long-lived object property.)

假设debounce实现释放了对它永远不会实现的promise的引用,并且promise的使用者没有在此相互引用周期之外的某个地方存储引用,那么promise和处理程序将向其注册(一旦发布了对Promise的引用,所有它们拥有的唯一引用都可以被垃圾回收.

Assuming the debounce implementation releases its reference to the promise that it's never going to settle, and the consumer of the promise hasn't stored a reference somewhere outside this mutual-reference cycle, then the promise and the handlers registered to it (and anything that they hold the only reference for) can all be garbage collected once the reference to the promise is released.

在实现方面需要相当的谨慎.例如,(感谢 Keith 进行举报),如果promise对某些内容使用了回调其他API(例如,addEventListener),并且回调在对promise的引用上关闭,因为另一个API对回调的引用,这可能会阻止所有对promise的引用都被释放,从而保留所有promise引用内存中的(例如其回调).

That requires a fair bit of care on the part of the implementation. For instance (thanks Keith for flagging this up), if the promise uses a callback for some other API (for instance, addEventListener) and the callback closes over a reference to the promise, since the other API has a reference to the callback, that could prevent all references to the promise from being released, and thus keep anything the promise refers to (such as its callbacks) in memory.

因此,这将取决于实现的谨慎性以及对使用者的影响.可能会编写代码来保留对Promise的引用,从而导致内存泄漏,但是在正常情况下,我不希望消费者这样做.

So it'll depend on the implementation being careful, and a bit on the consumer. It would be possible to write code that would keep references to the promises, and thus cause a memory leak, but in the normal case I wouldn't expect the consumer to do that.

这篇关于等待但从未解决/拒绝的承诺内存使用情况的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆