zoukankan      html  css  js  c++  java
  • 【翻译】Promises/A+规范

    介绍

    翻译Promises/A+规范的原因在于,在学习Promise时想要了解关于其规范的详细介绍,但是实际搜了很多文章的介绍似乎大多都是"残缺"的,有的文章虽然说是介绍Promises/A+规范,但其实或是简单介绍,或是做一些总结归纳;有的文章是有关Promises/A+规范的翻译,但是个人读起来感觉多处地方不太理解,有些语句也不通顺。于是后面干脆想着自己翻译一遍,也是对Promises/A+规范的一次认真学习。

    对译文的了解来自这篇[译]前端基础知识储备——Promise/A+规范文章,

    里面介绍了Promise/A+规范原文地址

    以及测试一个Promise库是否符合Promise/A+规范的工具promises-aplus/promises-tests

    注:fulfill履行,或完成,reject拒绝。对应于promise承诺

    译文

    一个完善的可互操作的JavaScript promises开放标准——来自开发者,为了开发者

    原文中后面结尾是——by implementers, for implementers,应该是表达promises来自于实际的实施使用者,为了实际的实施使用者

    一个promise代表一个异步操作的最终结果。与promise交互的主要方式是通过它的then方法,该方法注册回调函数以接收一个promise的最终结果或promise无法履行(fulfilled)的原因。

    该规范详细说明了then方法的行为,为所有符合Promises/A+的promise实现提供了一个可互操作的基础。因此,该规范可以被看作是非常稳定的。尽管Promises/A+组织有时会通过向后兼容的微小更改来修订此规范,以解决新发现的极端情况,但只有经过仔细考虑,讨论和测试之后,我们才会添加大的、或不向后兼容的更改。

    从历史上看,Promises/A+阐述了早期Promises/A提案的行为规范,将其扩展为涵盖事实的行为,并省略了未指定或有问题的部分。

    最后,Promises/A+规范的核心不涉及如何创建(create),履行(fulfill)或拒绝(reject)Promise,而是专注于提供可互操作的then方法。将来规范中的工作可能涉及这些主题。

    1. 术语(Terminology)

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

    1.2. "thenable"是定义一个then方法的对象或函数。

    1.3. "value"是任何合法的JavaScript值(包括undefined,, thenable, 或promise

    1.4. "exception"是一个使用throw语句抛出的值。

    1.5. "reason"是一个表明拒绝promise的原因的值。

    2. 要求(Requirements)

    2.1 Promise状态

    一个promise必须处于pendingfulfilledrejected三种状态之一。

    2.1.1. 当处于pending状态, 一个promise:

    • 2.1.1.1 可能转变为fulfilledrejected状态.

    2.1.2. 当处于fulfilled状态, 一个promise:

    • 2.1.2.1 无法转变为任何其他状态.
    • 2.1.2.2 必须有一个不可变的最终值.

    2.1.3. 当处于rejected状态, 一个promise:

    • 2.1.3.1 无法转变为任何其他状态.
    • 2.1.3.2 必须有一个不可变的原因(值).

    此处 "不可变" 表示全等(===),不代表深度比较相等。

    即:本可变(must not change)表示一旦变为fulfilledrejected状态,结果将不会再变更

    2.2 then方法

    一个promise必须提供一个then方法来访问其当前或最终的值,或者原因。

    promisethen方法接受两个参数:

    promise.then(onFulfilled, onRejected)
    

    2.2.1 onFulfilledonRejected都是可选参数

    • 2.2.1.1 如果onFulfilled不是函数,则它必须被忽略。

    • 2.2.1.2 如果onRejected不是函数,则它必须被忽略。

    2.2.2 如果onFulfilled是一个函数:

    • 2.2.2.1 它必须在promise变为fulfilled状态之后被调用, 并且promise的值(value)作为它的第一个参数.

    • 2.2.2.2 在promise变为fulfilled状态之前它一定不能被调用.

    • 2.2.2.3 它不能被调用超过一次。

    2.2.3 如果onRejected是一个函数:

    • 2.2.3.1 它必须在promise变为rejected状态之后被调用, 并且promise的原因(reason)作为它的第一个参数.

    • 2.2.3.2 在promise变为rejected状态之前它一定不能被调用.

    • 2.2.3.3 它不能被调用超过一次。

    2.2.4 onFulfilledonRejected只有在执行环境堆栈仅包含平台代码时才能被调用。3.1

    2.2.5 onFulfilledonRejected必须作为普通函数调用(例如,没有this值). 3.2

    2.2.6 同一个promise的then方法可以被调用多次

    • 2.2.6.1 如果(当)promise完成执行(fulfilled),onFulfilled回调必须按照它们原始的then调用时的顺序执行。
    • 2.2.6.2 如果(当)promise被拒绝(rejected)时,onRejected回调必须按照它们原始的then调用时的顺序执行。

    2.2.7 then方法必须返回一个promise 3.3

    promise2 = promise1.then(onFulfilled, onRejected);
    
    • 2.2.7.1 如果onFulfilledonRejected返回一个值x,则必须运行Promise解析程序[[Resolve]](promise2, x)

    • 2.2.7.2 如果onFulfilled或者onRejected抛出一个异常e ,则promise2必须被拒绝(rejected),并将e作为拒绝原因(reason)

    • 2.2.7.3 如果onFulfilled不是一个函数并且promise1完成执行(fulfilled),promise2必须以promise1相同的值作为结果也执行完成(fulfilled)

    • 2.2.7.4 如果onRejected不是一个函数并且promise1被拒绝(rejected),promise2必须以promise1相同的原因作为结果也被拒绝(rejected)

    2.3 Promise解析程序

    Promise解析程序是一个抽象的操作,用来处理作为输入的promise和值(value),表示为[[Resolve]](promise, x)。如果x是一个thenable,在假设x的行为至少类似于promise的情况下,会尝试使promise使用x的状态。否则,用值x履行(完成)promise

    这种对thenable的处理使promise实现了可互操作,只要该实现暴露一个符合Promises/A+then方法即可。同时也允许Promises/A+的实现"转化"那些不合格但是有合理的then方法的实现

    执行下面的步骤运行[[Resolve]](promise, x)

    2.3.1 如果promisex指向同一对象,那么用TypeError作为原因拒绝promise

    2.3.2 如果x是一个promise,则使用它的状态:

    • 2.3.2.1 如果x是pending,则promise必须保留pending直到x变为fulfilled或rejected

    • 2.3.2.2 如果(当)x是fulfilled,使用相同的值履行promise

    • 2.3.2.3 如果(当)x是rejected,使用相同的原因拒绝promise

    2.3.3 如果x是一个对象或函数:

    • 2.3.3.1 让then变为x.then 3.5

    • 2.3.3.2 如果获取x.then的结果时抛出错误e,使用e作为原因拒绝promise

    • 2.3.3.3 如果then是一个函数,将this执行x调用它,第一个参数是resolvePromise,第二个参数是rejectPromise,这里:

      • 2.3.3.3.1 如果resolvePromise使用值y被调用,则运行[[Resolve]](promise, y)

      • 2.3.3.3.2 如果rejectPromise使用原因r被调用,则使用r拒绝promise

      • 2.3.3.3.3 如果resolvePromiserejectPromise都被调用,或者使用相同参数多次调用,则优先使用第一个调用,任何其他调用将被忽略。

      • 2.3.3.3.4 如果调用then抛出一个异常e

        • 2.3.3.3.4.1 如果resolvePromiserejectPromise已经被调用,则忽略它
        • 2.3.3.3.4.2 否则,使用e作为原因拒绝promise
    • 2.3.3.4 如果then不是一个函数,使用x履行promise

    2.3.4 如果x不是一个对象或函数,使用x履行promise

    如果一个promise被一个环形thenable链中的thenable解决(resolved)(即thenable链是一个环形的循环链),那么[[Resolve]](promise,thenable)的递归性质最终会导致[[Resolve]](promise,thenable)再次被调用,按照上述算法将导致无限递归。我们鼓励检测此类递归并使用信息丰富的TypeError为原因拒绝promise,但此检测的实现不是必需的。 3.6

    3. 注释

    3.1 platform code

    这里的平台代码(platform code)是指引擎、环境和promise的实现代码。实际上,这要求确保在then调用的事件循环之后进入,并且使用的是新的堆栈异步执行onFulfilledonRejected。可以使用"宏任务"(macro-task)机制(如setTimeout或setImmediate)或"微任务"(micro-task)机制(如MutationObserver或process.nextTick)来实现。由于promise的实现被视为平台代码,因此在调用的处理程序中,它本身可能包含一个任务调度队列(task-scheduling queue)或"跳板"(trampoline,蹦床)

    3.2

    在严格模式中,函数内部的thisundefined;在松散模式中,this是全局对象

    3.3

    如果实现满足所有要求,则可以允许promise2 === promise1。每个实现都应说明其是否可以产生以及在什么条件下产生promise2 === promise1的结果。

    3.4

    通常,只有x来自当前的实现,才知道它是一个真实的promise。这允许那些特定的实现的采用已知的符合规则的promise的状态。

    3.5

    这个过程,首先存储对x.then的引用,然后测试该引用,然后调用该引用,避免了对x.then属性的多次访问。此类预防措施对于确保访问者属性的一致性非常重要,因为访问者属性的值在两次检索之间可能会发生变化。

    3.6

    实现不应在thenable链的深度上设置任意限制,并假定超出该任意限制,则递归将是无限的。只有真正的循环(环形循环)才应该导致TypeError;如果在一个无限链上遇到不同的thenables,则递归永远是正确的行为。

    后记

    第二部分是Promises/A+规范的整个译文,总体来说翻译真的不容易(除非英语特别牛,同时对编程有深厚的理解)。以上按照自己的理解大体进行了翻译,但难免有不正确或有歧义的地方,望理解并指出,一定加以改正。

    规范本身就比较晦涩难懂,或者文字简练精确,逻辑严谨准确。加上水平有限,总是很难看懂,不是看一遍就能理解或弄清楚的,在此共勉!

    作者: 代码迷途
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意原创文章必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    非原创文章若有需要,建议直接联系原文作者或保留声明情况下转载原文
  • 相关阅读:
    Spring Cloud Hystrix Dashboard的使用 5.1.3
    Spring Cloud Hystrix 服务容错保护 5.1
    Spring Cloud Ribbon 客户端负载均衡 4.3
    Spring Cloud 如何实现服务间的调用 4.2.3
    hadoop3.1集成yarn ha
    hadoop3.1 hdfs的api使用
    hadoop3.1 ha高可用部署
    hadoop3.1 分布式集群部署
    hadoop3.1伪分布式部署
    KVM(八)使用 libvirt 迁移 QEMU/KVM 虚机和 Nova 虚机
  • 原文地址:https://www.cnblogs.com/codemissing/p/JavaScript_PromiseA_Translation.html
Copyright © 2011-2022 走看看