我正在查看" Promises / A +"规范,但无法理解以下内容:
关于第1节。术语,
1.1。 "promise”
是一个带有then方法的对象或函数,其行为符合此规范。
1.2。 “thenable”
是定义then方法的对象或函数。
那么术语"thenable"
和"promise"
之间有什么区别?
同样在2.3节中。承诺解决程序,
承诺解决程序是一个抽象操作,将promise和值作为输入,我们将其表示为[[Resolve]](promise, x)
。
所以我的问题是:
为什么在2个开始和结束括号内表示?有没有约定?
非常感谢。
答案 0 :(得分:20)
那么术语“可以”和“承诺”之间有什么区别?
我认为您已经引用的部分确实很好地回答了这个问题:
then
方法的对象。任何对象。then
方法(即一个可用的)的对象。到目前为止这么简单。我认为你的实际问题是:“为什么要区分?”
问题在于,通过查看对象,您无法确定它是否是一个承诺
您可能能够告诉它这是一个承诺,因为您可以看到它的then
方法是由您自己或您信任的人实施的 - 通常是您选择的承诺库。您将能够“看到”因为对象确实从您的promise原型继承,或者您甚至可以比较与您定义的函数相同的(引用)方法。或任何其他足以满足您的检查方法
您可能能够告诉它不是承诺,因为它没有then
方法。
但是你如何处理一个实现then
的对象,但不知道是一个承诺呢?它是 thenable ,并将按此处理。
Promises / A +规范旨在实现promise实现之间的互操作性,并使用.then()
方法存在duck typing。它确实指定了一个关于如何处理这些可能性的精确算法(可能是承诺或至少具有相似的行为),以便您可以从它们创建一个实际的,可信的(“已知”)承诺。 / p>
为什么在2个开始和结束括号内表示?有没有约定?
是的,ECMAScript规范对internal methods and properties使用此语法:
内部属性的名称用双方括号[[]]括起来。
这些属性实际上并不需要存在,它们纯粹用于描述应该发生的事情 - 实现必须像一样使用它们。但它们完全是抽象的操作。
答案 1 :(得分:4)
这是一种聪明的尝试,可以让promises更容易在不同的库之间进行互操作。
规范在少数几个地方使用了术语thenable
。这是最重要的(empasis mine):
承诺解决程序是一个抽象操作,将promise和值作为输入,我们将其表示为
[[Resolve]](promise, x)
。 如果x是一个可以,它会尝试使x采用x的状态,假设x的行为至少有点像promise。否则,它使用值x履行承诺。
这将使实现者进行如下检查:
if (typeof(x.then) === 'function') {
// adopt the state of x
} else {
// fulfill promise with value x
}
如果规范改为说“如果x是一个承诺,那么......”,实施者将如何知道x
是否是一个承诺?没有实际的方法来确保x
是否符合Promise规范只是通过检查它。
实现者(比如,库FooPromises
可能会执行类似
if (x instanceof FooPromises.Promise) {
// adopt the state of x
} else {
// fulfill promise with value x
}
它会有效地拒绝来自不同实现的任何承诺。
相反,通过在这种情况下使用thenable
的超简单定义,实现者可以轻松验证,进行此检查并使实现彼此之间的相关性很好。
对于你的第二个问题,我不确定,但我的想法是一个符号[[Resolve]](promise, x)
强调它是一个抽象的操作。如果他们删除括号并只是说Resolve(promise, x)
,那么它会以某种方式暗示实现者应该创建一个名为Resolve
的真实函数并公开它。
这不是必需的 - Resolve
不是承诺界面的一部分;它只是他们行为的一部分,非常重要,它在文档中被赋予了一个名称和一个单独的部分。