关于Promises/A +规范,术语"可以"和"承诺"之间有什么区别?

aut*_*ode 25 javascript specifications specification-pattern promise

我正在检查"Promises/A +"规范,但无法理解以下内容:

在第1节.术语,

1.1."promise”是一个具有then方法的对象或函数,其行为符合此规范.

1.2.“thenable”是定义then方法的对象或函数.

那么术语"thenable"和有"promise"什么区别?

同样在2.3节.承诺解决程序,

promise解析过程是一个抽象操作,它将promise和value作为输入,我们将其表示为[[Resolve]](promise, x).

所以我的问题是:

为什么在2个开始和结束括号内表示?有没有约定?

非常感谢你.

Ber*_*rgi 23

那么术语"可以"和"承诺"之间有什么区别?

我认为您已经引用的部分确实很好地回答了这个问题:

  • 一个是一个带有then方法的对象.任何对象.
  • promise是一个具有符合规范then方法(即,thenable)的对象.

到目前为止这么简单.我认为你的实际问题是:" 为什么他们会被区分? "

问题在于,通过查看对象,您无法确定它是否是一个承诺.
可能会告诉它这是一个承诺,因为您可以看到它的then方法是由您自己或您信任的人实现的 - 通常是您选择的承诺库.您将能够"看到"因为对象确实从您的promise原型继承,或者您甚至可以比较与您定义的函数相同的(引用)方法.或任何其他足以满足您的检查方法.
可能会告诉它它不是一个承诺,因为它没有then方法.
但是你如何处理一个实现的对象then,但不知道是一个承诺?这是一个很好的,并将按此处理.

Promises/A +规范旨在实现promise实现之间的互操作性,并使用鸭子类型.then()方法的存在.它确实指定了一个关于如何处理这样的可能性(可能是承诺或至少具有类似行为)的精确算法,以便您可以从它们创建实际的,可信的("已知")承诺.

为什么在2个开始和结束括号内表示?有没有约定?

是的,ECMAScript规范将此语法用于内部方法和属性:

内部属性的名称用双方括号[[]]括起来.

这些属性实际上并不需要存在,它们纯粹用于描述应该发生的事情 - 实现必须使用它们一样.但它们完全是抽象的操作.

  • 非常好的答案。从规范中展示 thenable 是多么不可信的例子可能会很好 - 规范防止 getter、抛出的 thenable、吸收抛出的 thenable 的 thenable 等等。 (2认同)

Kos*_*Kos 5

这是一个明智的尝试,可以使Promise在不同库之间更易于互操作。

规范thenable仅在少数地方使用该术语。这是最重要的(empasis矿):

承诺解决程序是一个抽象操作,将承诺和值作为输入,我们将其表示为[[Resolve]](promise, x)如果x是thenable,则在x的行为至少类似于promise的假设下,尝试使promise采用x的状态。否则,它会以值x履行承诺。

这将使实现者进行如下检查:

if (typeof(x.then) === 'function') {
    // adopt the state of x
} else {
    // fulfill promise with value x
}
Run Code Online (Sandbox Code Playgroud)

如果规范改为说“如果x是一个诺言,那么...”,那么实现者将如何知道是否x是一个诺言?没有实际的方法来x仅通过检查来确保是否符合Promise规范。

一个实现者(例如,库FooPromises可能会做类似

if (x instanceof FooPromises.Promise) {
    // adopt the state of x
} else {
    // fulfill promise with value x
}
Run Code Online (Sandbox Code Playgroud)

它将有效地拒绝来自不同实现的任何承诺。

相反,通过thenable在这种情况下使用实现者可以轻松验证的超简单定义,进行此检查很容易,并且使实现彼此之间可以很好地发挥作用成为可能。


对于第二个问题,我不确定,但是我的想法是用一种符号[[Resolve]](promise, x)强调它是一种抽象操作。如果他们放括号并只是说了Resolve(promise, x),那将意味着执行者应以实名函数命名Resolve并公开它。

不需要-这不是ResolvePromise接口的一部分;仅仅是他们行为的一部分就足够重要了,因此在文档中给了它一个名称和一个单独的部分。