当前位置: 首页 > 知识库问答 >
问题:

promise/规范和ECMAScriptpromise之间可能存在矛盾?

左丘边浩
2023-03-14

声明ECMAScript promises是Promissions/a实现,因此它们没有矛盾。然而,我遇到了ecmapromise的行为,据称该行为与promise/a不符。

当我们呼叫promise1时。然后(onCompleted,onRejected)为了收听promise1的输出,我们得到另一个promise(promise2)作为返回值。当执行所需的回调(oncompleted/onRejected)时,它又返回了一些值x,规范规定使用定义的[[resolve(promise2,x)]]函数来解析它。假设x恰好是一个promise本身(x===promise3),那么必须采取以下步骤:

  • 如果x是一个promise,则采用其状态:
  • 如果x是挂起的,promise2必须保持挂起,直到x被满足或拒绝。
  • 如果/当x实现时,用相同的值实现promise2
  • 如果/当x被拒绝时,以相同的理由拒绝promise2

我想知道如果x最终实现了另一个promise(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

换句话说,promise2是用promise4的值来实现的。这种行为类似于规范中为其他thable对象定义的行为。所以ECMAScriptpromise不进行预期的类型检查,只是检查是否x然后方法?

共有2个答案

刁浩言
2023-03-14

从规范摘录可以得出结论,promise2也必须符合promise4

不,这不符合promise/A规范。你引用的规则

  • 如果履行了x,则使用相同的值履行promise2

...本质上是递归的。应更详细地理解如下:

如果/当履行了x时,履行promise2,使用与履行x相同的值。

现在,对于“用x实现的”部分,同样的解决程序适用(!):事实上,当x用另一个thable(promise4)解决时,它反过来会被锁定在链(在您的示例中为promise4)。这还不是实现的价值。解决和实现之间有一个重要的区别。解析过程的第二次执行将确保x满足的值是promise4满足的值。

锁定promise链可以有任意长度,但原则保持不变:每个promise都将通过此promise/解决程序锁定到下一个promise来解决。当此链中的最后一个实现时(使用非thenable值),则锁定的所有promise都将使用此值实现。

翟鸿振
2023-03-14

让我们假设x碰巧是一个promise本身,那么必须采取的步骤如下:[...]

不,它们不需要被拿走——只有当x是一个“promise”时,它们才可以被拿走。这些步骤是可选的(“允许的”,而不是“必需的”)优化:

注意4:
通常,只有当它来自当前实现时,才会知道x是一个真正的promise。该条款允许使用特定于实现的手段来采用已知符合promise的状态。

ECMAScript不把它自己的Promise视为已知的符合,忽略了这些步骤。他们只是像对待所有其他线一样对待原生promise。鉴于没有办法创建一个ECMAScriptPromise,它用另一个promise来实现,这相当于直接采用状态。

 类似资料:
  • 问题内容: 我知道defer分隔诺言状态的控制和过程,这里以Q为例,返回的诺言和完全不同,为什么这样设计?这两个“承诺”有什么区别 问题答案: 好吧,这是关于承诺解决方案源的。Q和其他许多库提供两个API: 旧版API-您可以在其中创建一个递延函数, 并承诺可以返回。 Promise构造函数 -这是现代API,您可以在其中从完成源创建Promise。 粗略地做: 是相同的: 所以你可能会问 为什么

  • 问题内容: Dockerfile有一个用于 ENTRYPOINT 的参数,并且在编写Kubernetes部署YAML文件时,在Container规范中有一个用于 COMMAND 的参数。 我不知道有什么区别以及如何使用它们? 问题答案: Kubernetes为我们提供了有关如何使用这些命令的多种选择: 当您覆盖Kubernetes .yaml文件中的默认Entrypoint和Cmd时,将应用以下规

  • 在AngularJS中可观察到的和promise之间的区别?在angular 2和angular 4版本中,promise和观测值有哪些变化?解释这种情况的例子会有很大帮助。

  • 公司及产品名称 我们的公司及产品名称是「DaoCloud」。注意这是两个单词的合成词,所以中间沒有空格(参考:GitHub)。如作为 URL 的一部分,应该使用全小写的「daocloud」。 文案风格 一定多检查,确保没有错别字。 即使是流行语中的谐音错别字也不要使用,比如「墙裂」、「童鞋」等。 我们崇尚精练的文风。请在检查中把对表达意思没有明显作用的字、词、句删除,在不影响表达效果的前提下把文案

  • 我想创建基于JPA规范的过滤器。我正在使用Spring数据。 我的实体: 实体依赖项为:第1节-一对多- 我有一个转换为规范的问题过滤器类。我想了解第节中的所有问题。 通常,我会使用下面编写的SQL查询来获取部分中的所有问题。 我尝试过使用Join创建规范,但不知道如何在问题上的目标参考不可用时创建连接。

  • This is a sample functional specification, a part of Joel on Software, a site about software management. It is intended for educational purposes, not to refer to a real product, in case you didn't not