【问题标题】:Are there any (negative) side effects when I don't use the "then" function of a Promise?当我不使用 Promise 的“then”功能时,是否有任何(负面)副作用?
【发布时间】:2015-12-16 16:27:14
【问题描述】:

我有一个返回 Promise 的函数。

现在,有时消费者在该 Promise 上使用“then”函数是有意义的。但有时消费者根本不关心 Promise 何时解析,也不关心结果 - 换句话说,同样的函数也应该能够以“即发即弃”的方式调用。

所以我想要这两种使用场景:

func().then( ... ); // process Promise
func(); // "fire and forget"

这显然有效,但我想知道这是否被认为是“不好的做法”,特别是这种使用模式是否会产生任何不需要的副作用,即。导致内存泄漏?现在我正在使用 bluebird,但如果这有什么不同,我会考虑切换到原生 Promises。

【问题讨论】:

  • +1,虽然我认为这不会引起任何问题。但正如你所问的内存泄漏..我很想知道:)
  • Can I fire and forget a promise in nodejs (ES7)? 的可能重复项(使用async/await 语法,但前提相同)
  • 是的,Bergi 听起来至少很相似 - 抱歉,我在搜索答案时没有找到这个。唯一的区别是我没有使用节点。

标签: javascript promise


【解决方案1】:

请记住,每次调用 then 都会产生一个新的承诺。因此,任何由于 Promise 没有附加任何解析处理程序而导致内存泄漏的 Promise 实现都将是一个损坏的实现,所有那些我们永远不会挂钩处理程序以返回的承诺。我非常怀疑 ES2015 的 promises 的实现,Bluebird、Q 等是否有这种行为。

另外,从概念上讲,promise 的解析处理程序基本上只是由 promise 存储的函数,然后在适当的时候调用,如果你从不给​​它任何存储的函数,它不太可能是内存泄漏。

但是,你的即发即弃存在问题,而不是内存泄漏问题:它违反了主要的 Promise 规则之一:要么处理拒绝,要么将 Promise 链返回到其他可以处理拒绝的东西。由于您没有这样做,因此如果操作失败,您将收到未处理的拒绝。未处理的拒绝会报告给控制台,并且在某些环境中可能会终止您的应用程序(在某些时候,Node.js 可能会在发生这种情况时开始终止进程​​,请参阅this open issue)。

如果then 返回一个新的承诺这一事实令人惊讶,请考虑:

let p1 = new Promise(resolve => {
  setTimeout(() => {
    resolve('a');
  }, 100);
});
let p2 = p1.then(result => {
  console.log("p1.then got " + result);
  return 'b';
});
p2.then(result => {
  console.log("p2.then got " + result);
});

哪个输出

p1.then 得到一个 p2.然后得到b

【讨论】:

  • 我没有解决“不良做法”部分,因为这可能是主观的。但我会注意到,不使用函数的返回值是很常见的,这可以说是不向承诺添加任何处理程序的非承诺等价物。
  • @T.J.Crowder - 那么您对 ​​OP 的回答是什么“这会导致任何问题/意外副作用或内存泄漏”?听起来您对 OP 的回答是“否”,或者...?
  • @DonCheadle - 我想我在开头的段落中提到了这一点。不,它不会导致内存泄漏。 :-)
猜你喜欢
  • 2013-11-18
  • 1970-01-01
  • 2012-12-14
  • 2019-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-15
  • 2019-08-17
相关资源
最近更新 更多