承诺多次解决后会发生什么

时间:2017-04-12 06:03:42

标签: javascript es6-promise

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

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

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

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

更新

对不起,我刚才意识到它不是一个polyfill,而只是一个Promise(非标准)的最小实现。

2 个答案:

答案 0 :(得分:8)

承诺无法解决多次。一旦承诺得到解决(解决或拒绝),将再次调用解决(解决或拒绝)协议。没有错误。

  

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

不,它没有。 Promise Resolve Functions中介绍了这一点,它说明了它们的作用。以下是前四个步骤:

  

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

     
      
  1. 断言:F有一个[[Promise]]内部插槽,其值为Object。
  2.   
  3. 承诺是F [[Promise]]内部插槽的价值。
  4.   
  5. 让hasResolved为F [[AlreadyResolved]]内部插槽的值。
  6.   
  7. 如果已经解决。[[Value]]为true,则返回undefined。
  8.   
  9. ...
  10.   

(我的重点)

有些人认为,试图解决既定的承诺应该是一个错误。由于这不符合ES2015的规范,因此可能很难添加它,即使他们能够找到TC-39冠军来提出这样做​​。它可能最终必须是一个标志或Promise子类,如果这是你想要的行为,可以很容易地添加一个自己的Promise子类。

答案 1 :(得分:3)

根据ECMAScript 2015 Language Spec

  

承诺对象

     

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

     

任何Promise对象都处于三种互斥状态之一:已履行,已拒绝和待处理:   如果p.then(f,r)将立即将Job排入队列以调用函数f,则实现promise p。   如果p.then(f,r)将立即将Job排入队列以调用函数r,则拒绝promise p。   如果未履行或拒绝,则承诺正在等待。   如果一项承诺没有待决,即如果它已被履行或被拒绝,则该承诺将被解决。

     

如果一个承诺已经解决,或者它已被“锁定”以匹配另一个承诺的状态,则该承诺将得到解决。 尝试解决或拒绝已解决的承诺无效。如果未解决,承诺将无法解决。未解决的承诺始终处于暂挂状态。已解决的承诺可能正在等待,履行或拒绝。