(相关但不完全相同: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 有时特别用于表示履行,有时履行/拒绝/锁定,即使在最权威的文档中也是如此?
答案 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'
。
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;
所以即使你resolve()
- 你的承诺的当前操作,你也不知道之后会发生什么,所以你不知道最后它是fulfilled
{1}}或rejected
。