首页 > 解决方案 > 如果没有 JavaScript 中的 .then(),承诺可能会过早地被垃圾收集

问题描述

所以基本上我想异步执行 2 个同步承诺。像这样:

(function foo() {
  var newValues = ...;
  this.getMessages().then((msgs: Array<any>) => {
    this.saveMessages(msgs.concat(newValues));
  });
})()

现在因为我不想等待saveMessages完成执行,所以我没有.then()在最后添加 a 。因为我不在乎结果。我只想执行异步函数,所以在某些时候我们让消息离线。

但我担心承诺可能会被垃圾收集,因为按照标准(据我所知)你总是需要一个.thenfor 承诺。

所以我的问题是我是否需要添加一个空.then的以确保它不会太早地被垃圾收集并且函数不会正确执行。像这样:this.saveMessages(msgs.concat(newValues)).then();

在浏览器和 NodeJS 中是否相同?

标签: javascriptnode.jspromisees6-promise

解决方案


但我担心承诺可能会被垃圾收集,因为按照标准(据我所知)你总是需要一个.then()for 承诺。

不。不存在任何这样的标准——据我所知——该标准规定Promise如果 a.then()未附加到 a 对象,GC 将释放分配给 a 对象的内存。

.then()无论是否附加了- 或a .catch()就此而言 - Promise 都会被执行。

所以我的问题是我是否需要添加一个空.then()的以确保它不会太早地被垃圾收集并且函数不会正确执行。

不,你不需要一个空的.then()

在浏览器和 NodeJS 中是否相同?

是的,只要您Promise在两个运行时都使用相同的实现。


所以,你会完全没问题:

function foo() {
  var newValues = ...;
  this.getMessages().then((msgs: Array<any>) => {
    this.saveMessages(msgs.concat(newValues));
  });
}

但是,您应该考虑将 a 附加.catch()到它以处理任何错误。如果你不这样做,你将拥有UnhandledPromiseRejectionWarning. 在 Node 的未来版本中,它可能会使您的整个应用程序崩溃。在这里阅读

编辑

即使父进程没有任何东西要处理或执行,程序也会等到 100 个 Promise 中的每一个都已解决。试试这个:

const n = 100;

const sleep = (id, seconds) =>
    new Promise(resolve => {
        setTimeout(() => {
            console.log(`promise with id ${id} is resolving`);
            resolve();
        }, seconds * 1000);
    });

for (let i = 0; i < n; i++) {
    sleep(i, 1 * i);
}

console.log("Last line of parent");

推荐阅读