【问题标题】:What happens when a promise is resolved multiple times当一个承诺被多次解决时会发生什么
【发布时间】:2017-09-07 18:13:37
【问题描述】:

如果 ES6 承诺被多次拒绝/解决,标准行为是什么?

以下代码仅在Google Chrome 中解析一次,这是所有浏览器的标准行为吗?

new Promise(function(e) {
    $('#button').click(function(){
        resolve();
    });
});

我看到promise polyfill 在尝试解决已解决的承诺时抛出异常。 es6-promise 的规范是否指定了这一点,还是不符合 polyfill 标准?

更新

抱歉,我刚刚意识到它不是 polyfill,而只是 Promise 的最小实现(非标准)。

【问题讨论】:

  • 答案的结果是,不要使用未命名的 polyfill,因为它不是“标准”
  • 你确定你看到的 promise 库是一个 polyfill 吗? ES2015 标准将 Promise 内置到 JavaScript 之前,有多个 Promise 库。

标签: javascript es6-promise


【解决方案1】:

一个承诺不能多次解决或解决。一旦承诺被解决、履行或拒绝,进一步的解决或解决它的调用将被忽略。 (如果这些术语不熟悉或只是模糊地熟悉,我已经写过有关 promise 术语的文章 on my blog。) 不会引发错误。

我看到一个 promise polyfill 在尝试解决已解决的 promise 时抛出异常。 es6-promise 的规范是否指定了这个...?

没有。 Promise Resolve Functions 对此进行了介绍,其中说明了他们的工作。以下是最初的几个步骤:

当使用参数解析调用 promise resolve 函数时,将执行以下步骤:

  1. F 为活动函数对象。
  2. 断言:F 有一个 [[Promise]] 内部槽,其值为对象。
  3. promiseF。[[Promise]]。
  4. alreadyResolved 为 F.[[AlreadyResolved]]。
  5. 如果 alreadyResolved.[[Value]] 为真,则返回 undefined。

(我的重点)

有些人认为,试图解决或解决已经解决或解决的承诺应该是错误的。由于它没有被纳入 ES2015 规范,它可能永远不会被添加,因为它不会与现有代码向后兼容。

【讨论】:

    【解决方案2】:

    根据ECMAScript 2015 Language Spec

    承诺对象

    Promise 是一个对象,用作延迟(也可能是异步)计算的最终结果的占位符。

    任何 Promise 对象都处于三种互斥状态之一:已完成、已拒绝和待处理: 如果 p.then(f, r) 将立即将 Job 加入队列以调用函数 f,则实现了 Promise p。 如果 p.then(f, r) 将立即将 Job 加入队列以调用函数 r,则 Promise p 被拒绝。 如果既没有实现也没有拒绝,则 Promise 处于待处理状态。 如果一个 Promise 不是未决的,即它要么被履行,要么被拒绝。

    如果一个 Promise 已解决,或者它已被“锁定”以匹配另一个 Promise 的状态,则该 Promise 被解决。 尝试解决或拒绝已解决的承诺无效。如果未解决,则承诺未解决。未解决的承诺始终处于待处理状态。已解决的 Promise 可能处于未决、已完成或已拒绝。

    【讨论】:

      猜你喜欢
      • 2017-08-26
      • 1970-01-01
      • 2018-03-07
      • 1970-01-01
      • 2021-12-22
      • 2016-08-12
      • 2017-05-09
      • 2013-10-05
      相关资源
      最近更新 更多