【问题标题】:What will happen when return new Promise((resolve, reject) => {}) forgot to call either resolve or reject? [duplicate]当 return new Promise((resolve, reject) => {}) 忘记调用resolve或reject时会发生什么? [复制]
【发布时间】:2019-09-15 15:14:15
【问题描述】:

问题是这样的

function demo() {
    return new Promise((resolve, reject) => {
        ...
        // The problem here!!
        //I just found in some rare case we failed to call resolve or reject
    })
}

demo()
    .then(res => {
        console.log('resolve')
        console.log(res)
    })
    .catch(rej => {
        console.log('reject')
        console.log(rej)
    })
    .finally(() => {
        console.log('why')
    })

当我调用resolve或reject失败时,连finally块都没有被调用!为什么?

我原以为这是一个错误,然后我发现原作者似乎故意这样做,如果他没有调用 resolve 或 reject,则不应调用 then/catch/finally,即在这种情况下 不应采取后续行动

但是这是一种有效的方式来处理不应该采取后续行动的情况吗?会不会有什么麻烦?

-----更新-----

即使我的问题被标记为重复,我仍然对我得到的答案不满意。最初我认为让 Promise 永远处于待处理状态是个坏主意。

但是 SO 中的答案说“应该没有副作用。”
Does never resolved promise cause memory leak? 还说“简而言之 - 至少在现代浏览器中 - 你不必担心未解决的承诺,只要你没有对它们的外部引用”。因此,如果这是目的,让 promise 处于待处理状态似乎是可以的。

【问题讨论】:

  • 是的,正如预期的那样——如果既没有调用resolve 也没有调用reject,Promise 不知道异步操作已经完成,因此没有任何处理程序附加到 Promise 运行。但是永远挂起的承诺是一个坏主意 - 最好修复代码,以便它最终解决或拒绝
  • 我不这么认为,因为如果 thencatch 都没有被调用,这会让 demo 的消费者感到困惑。我认为最好解决(或拒绝)包含表明不应再做任何事情的信息的内容,例如resolve('No action needed')
  • 只有修复返回 Promise 的函数 - 你必须重构 demo
  • demo 实际上在做什么?我无法想象不解决 Promise 的场景是有意义的。
  • @Qiulang 它可以工作(如您所见,没有任何反应),但我仍然认为这是一种不好的做法:它违背了大多数人的期望,就像 finally 从未发生过一样。非终止循环同样糟糕。

标签: javascript node.js promise es6-promise


【解决方案1】:

在内部,promise 可以处于以下三种状态之一:

Pending,当最终值尚不可用时。这是唯一可以转换到其他两种状态之一的状态。 已实现,最终值何时以及是否可用。履行价值与承诺永久关联。这可以是任何值,包括未定义的。 拒绝,如果错误导致最终值无法确定。拒绝原因与承诺永久关联。这可以是任何值,包括 undefined,尽管它通常是一个 Error 对象,就像在异常处理中一样。

https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Promise.jsm/Promise

在您的情况下,承诺处于待处理状态,调用演示函数将始终等待承诺状态被履行或拒绝。

【讨论】:

  • 我原以为“调用 done 函数将始终等待承诺状态被履行或拒绝。”但是我发现调用 done 函数实际上是继续运行而不是挂在那里。
  • calling done function 所以,你们俩都没有处理承诺,没有 done 功能......then/catch 和最近的finally -后两者只是.then 的变体(糖)
  • @JaromandaX 我知道没有 done 函数,我的意思是调用函数没有挂起。
  • 它实际上是错字它是演示功能而不是完成
  • @RajeshKrVerma 感谢您的回答,但我无法让您的回答成为可接受的 b/c 我已经知道您所说的,我不认为“调用演示功能将始终处于等待状态”跨度>
【解决方案2】:

您可以使用Promise.race 检查承诺是否按时完成。 因此,如果您忘记在您的承诺中调用resolvereject,那么Promise.race 在延迟后仍然会被解决或拒绝。

var promise1 = new Promise(function(resolve, reject) {
    setTimeout(reject, 500);
});

var promise2 = new Promise(function(resolve, reject) {

});

Promise.race([promise1, promise2]).then(function(value) {
  console.log(value);
}).catch(err => console.log('promise rejected'));

【讨论】:

    【解决方案3】:

    一个承诺总是被期望要么解决要么拒绝。 如果您不打算跟进,您可以使用空数据集解决或使用适合您用例的错误代码拒绝。

    【讨论】:

      猜你喜欢
      • 2019-04-07
      • 2019-01-20
      • 2015-11-15
      • 1970-01-01
      • 2018-10-10
      • 2016-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多