首页 > 解决方案 > Promises/A+ 规范和 ECMAScript 承诺之间可能存在矛盾?

问题描述

断言ECMAScript 承诺是Promises/A+ 实现,因此它们没有矛盾。但是,我遇到了一个据称与 Promises/A+ 不一致的 ecma promises 行为。

当我们调用promise1.then(onFulfilled, onRejected)监听promise1的输出时,我们得到另一个 promise () 作为返回值promise2。当所需的回调 ( onFulfilled/onRejected) 被执行并且它反过来返回一些值时,规范规定使用定义的函数x来解决它。[[Resolve(promise2, x)]]假设x碰巧是一个promise本身(x === promise3),那么必须采取的步骤如下:

  • 如果x是一个承诺,采用它的状态:
  • 如果x是待处理的,则promise2必须保持待处理状态,直到x完成或拒绝。
  • 如果/何时x满足,promise2则以相同的值满足。
  • 如果/何时x被拒绝,promise2以同样的理由拒绝。

我想知道如果x最终实现了另一个承诺 ( promise4) 会怎样(没有任何阻碍,是吗?)。promise2也可以从必须满足的规范摘录中得出结论promise4。但在 ECMAScript 世界中似乎并非如此:

let promise4 = new Promise((resolve) => { resolve(4) })

let promise3 = new Promise((resolve) => {
    resolve(promise4);
});

let promise1 = new Promise((resolve) => {
    resolve(1);
});

let promise2 = promise1.then((val) => { return promise3 });
promise2.then(val => console.log(val)); // output: 4

换句话说,promise2promise4' 值实现。此行为类似于规范中为其他thenable对象定义的行为。那么ECMAScript promises不进行预期的类型检查并且只检查是否xthen方法吗?

标签: javascriptpromise

解决方案


假设x碰巧是一个承诺本身,那么必须采取的步骤如下:[…]

不,它们不需要被采纳——只有x在“承诺”的情况下才会被采纳。这些步骤是可选的(“允许”,而不是“必需”)优化:

注 4:一般来说,只有当它来自当前的实现时
,才会知道它是一个真正的 Promise。x本条款允许使用特定于实现的方法来采用已知符合承诺的状态。

ECMAScript 不会将其自己Promise的 s 视为“已知符合”,忽略这些步骤。他们只是像对待所有其他 thenables 一样对待原生 Promise。鉴于无法创建一个Promise用另一个 promise 实现的 ECMAScript ,这相当于直接采用状态。


推荐阅读