是"解决"始终意味着与"履行"?

时间:2017-01-28 11:23:55

标签: javascript terminology es6-promise

(相关但不完全相同:JS Promises: Fulfill vs Resolve

我一直在努力解决Javascript承诺问题,而且我正在努力解决 resolve 已解决的基本概念,以及履行履行。我已阅读了几篇介绍,例如Jake Archibald's,以及浏览some relevant specs

States and Fates中(不是官方规范,但是作为一个规范作者编写的权威文档引用),履行是一个状态,而已解决是命运" (不管是什么 - 但他们明显不同):

  

承诺有三种可能的互斥状态:履行,   拒绝,等待。

     
      
  • 承诺已履行如果promise.then(f)将调用f"只要   。可能"
  •   

  

如果尝试解决拒绝已解决承诺,则无效   即承诺已经被锁定在"要么跟随另一个   承诺,或已经履行拒绝

特别是,已解决包含已履行已拒绝(以及已锁定在中)。 "对面" (或直接相应的功能)拒绝履行,而不是解决; 解决 包含 拒绝作为其可能性之一。

然而spec使用履行解决来引用then()方法(或其相应的抽象概念)的第一个参数:

  •   

    25.4:承诺p 已履行如果p.then( f ,r)将立即将作业排入队列以调用函数f。

  •   

    25.4.1.1:[[ Resolve ]]一个函数对象用于解析给定的promise对象的函数。

  •   

    25.4.1.3:将解决的[[Promise]]内部插槽设置为promise。   将解决的[[AlreadyResolved]]内部插槽设置为alreadyResolved。 [然后紧接着,拒绝以完全相应的方式使用。]

  •   

    25.4.5.3:Promise.prototype.then( onFulfilled ,onRejected)

也许最重要的一个是

  •   

    25.4.4.5承诺。解决(x)

其中MDN描述如下:

  

Promise.resolve(value)方法返回使用给定值解析的Promise对象。如果值是一个值(即具有"那么"方法),则返回的promise将"跟随"那么可靠,采用其最终状态;否则,返回的承诺将履行并带有值。

没有提及可能拒绝Promise.resolve()方法。此外,还有Promise.reject()方法,但没有Promise.fulfill()方法。所以在这里,拒绝的对应部分是解决,而不是履行

当然," fate"之间可能没有保证相关性。术语已解决,方法(或动词)已解决。但是当履行时,resolve()将承诺置于特定的履行状态会是(真的吗?)真的会误导和混淆已经仔细定义已经解决的具有不同的含义。

这就是发生在这里的事情......右手不知道左手在做什么,我们最终得到的文件应该是运动的指路灯,使用不一致的术语方法?或者是否有我遗漏的内容, resolve 实际上是一个比履行更合适的术语,用于resolve()方法的作用?

我不是故意要批评文档作者。我理解,对于广泛分布的群体而言,在历史上,如何在所有文档中始终如一地使用所有术语是很困难的。我在这里挖掘这些文档的术语和措辞的目的是准确理解这些术语 - 其中包括了解完成解决之类术语的限制。可以真正区分。 Jake Archibald admits他有时会把条款搞砸了。对于那些试图理解术语的像我这样的新手来说,这是非常有帮助的!杰克,谢谢你的弱势。 :-)我提出这个问题的目的是找出这些术语 可靠的定义或用法?或者我应该得出结论 resolve 有时特别用于表示履行,有时履行/拒绝/锁定,即使在最权威的文档中也是如此?

2 个答案:

答案 0 :(得分:2)

  

我正在努力解决 resolve 已解决的基本概念,而履行已实现

看看What is the correct terminology for javascript promises。是的,他们有时会混淆,但让我们试着忽略它。

  

然而,规范引用了使用履行解决then()方法(或其相应的抽象概念)的第一个参数。我们是否以不一致的方式结束了应该成为运动指导灯的文件?

不,这里没有不一致之处,规范中的条款是准确的。

resolve reject 不同,onFulfilled回调与解析并不完全对应。

  

或者是否有我遗漏的内容, resolve 实际上是一个比履行更合适的术语,用于resolve()方法的作用?< / p>

是。问题是你可以解决一个承诺(或者一般来说,一个版本,即任何一个then方法的对象),而不是满足于该对象,解决的承诺将尝试用theable的结果来实现。或者当那个人有(会有)一个错误时,它会以此为理由拒绝。

  

[在MDN中]没有提及Promise.resolve()方法有可能拒绝

实际上有:&#34; 返回的承诺将&#34;跟随&#34;那么,采用最终状态&#34;。如果该最终状态是错误状态,则返回的promise也将拒绝。

  

Promise.reject()方法,但没有Promise.fulfill()方法。所以在这里,拒绝的对应部分是解决,而不是履行

是的,ES6承诺缺少Promise.fulfill方法。这一点有点不一致和令人困惑,但是有充分理由这样做:它阻止你有一个履行了另一个承诺的承诺。您只能解析 ES6承诺,当您传递承诺时,它将自己的结果而不是承诺对象。

这非常有用,但也非常不方便。有些图书馆可以做得更好并允许这种情况,它们就是所谓的&#34; 代数承诺&#34; (你可以推理得更好)。 Creed就是一个很好的例子,它的Promise.of方法与Promise.reject完全相同。

答案 1 :(得分:1)

让我们在其中一个引号中强调其他地方:

  

如果试图解决或拒绝承诺,则承诺得到解决,即承诺已经被锁定在&#34;要么遵循另一个承诺,要么已经履行或被拒绝

reject()会将您的承诺和所有先前链接的状态更改为rejected
虽然resolve()会锁定您当前的Promise,但只有解析回调的实现才会将其状态设置为fulfilled。只要一切都没有完成,您的承诺仍然是'pending'

例如,如果您链​​接Promise,并且在链中发生错误,则会将Promise的状态设置为'rejected'

&#13;
&#13;
var p = new Promise((resolve, reject) => {
  resolve(); // here p is resolved, we can't call resolve() or reject() anymore
}).then((e) => { // chain it
  return new Promise((resolve, reject) => {
    console.log(p); // 'pending' because it's still chained
    reject('whatever') // this one throws an error and breaks the chain
  })
}).then(() => console.log('passed')); // won't happen


setTimeout(() => console.log(p, "please check in your browser's console"), 1000); // rejected
&#13;
&#13;
&#13;

所以即使你resolve() - 你的承诺的当前操作,你也不知道之后会发生什么,所以你不知道最后它是fulfilled {1}}或rejected