介绍

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

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

【翻译】Promises/A+规范的更多相关文章

  1. 前端翻译:Promises/A+规范

    原文地址:https://promisesaplus.com/ 本篇为原文翻译+个人理解,若有谬误请各位指正,谢谢. 尊重原创,转载请注明来自:http://www.cnblogs.com/fsjoh ...

  2. CommonJS Promises/A规范

    本文来自四火哥的翻译 CommonJS是一组javascript编程规范,而promise是其中之一. 简而言之,promises是一种令代码的异步行为变得更加优雅的软件抽象.在基本的定义中,代码可能 ...

  3. JavaScript中Promises/A+规范的实现

    Promises是一种异步编程模型,通过一组API来规范化异步操作,这样也能够让异步操作的流程控制更加容易. 下面的代码是假设执行一个异步队列,每一项都会使用上一项返回的数据: function ne ...

  4. JS魔法堂:剖析源码理解Promises/A规范

    一.前言 Promises/A是由CommonJS组织制定的异步模式编程规范,有不少库已根据该规范及后来经改进的Promises/A+规范提供了实现 如Q, Bluebird, when, rsvp. ...

  5. 一起学习造轮子(一):从零开始写一个符合Promises/A+规范的promise

    本文是一起学习造轮子系列的第一篇,本篇我们将从零开始写一个符合Promises/A+规范的promise,本系列文章将会选取一些前端比较经典的轮子进行源码分析,并且从零开始逐步实现,本系列将会学习Pr ...

  6. 对 Promises/A+ 规范的研究 ------引用

    作为 Modern JavaScript 基础设施的一部分,Promises 对前端开发者而言异常重要.它是 async/await 语法的基础,是 JavaScript 中处理异步的标准形式.并且, ...

  7. Promises/A+规范

    为什么需要异步编程方式 一个函数执行之后,在它后面顺序编写的代码中,如果能够直接使用它的返回结果或者它修改之后的引用参数,那么我们通常认为该函数是同步的. 如果一个函数的执行结果或者其修改的引用参数, ...

  8. [iOS翻译]Cocoa编码规范

        简介: 本文整理自Apple文档<Coding Guidelines for Cocoa>.这份文档原意是给Cocoa框架.插件及公共API开发者提供一些编码指导,实质上相当于Ap ...

  9. [JavaScript] promise概述

    promise promise 是 es6 提出的一个异步解决方案,比传统回调事件的写法更加合理更加强大,主要还是优雅 promise 有 pending(等待中),fulfilled(已成功),re ...

随机推荐

  1. 趣学Python编程PDF高清完整版免费下载|百度网盘

    百度网盘:趣学Python编程PDF高清完整版免费下载 提取码:ts47 内容简介 python是一款解释型.面向对象.动态数据类型的高级程序设计语言.python语法简捷而清晰,具有丰富和强大的类库 ...

  2. 面试题三十:包含min函数的栈

    定义一个栈的数据结构,请实现一个每次都能找到栈中的最小元素,要求时间复杂度O(1).意思就是说每次进栈出栈后,min函数总能在时间1的前提下找到.方法一:由于每次循序遍历栈的话时间复杂度为n,所以要想 ...

  3. 为什么学习vue?

    公司要求学习uni-app,了解了一下这个uni-app uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS.Android.H5.以及各种小程序(微 ...

  4. 学习python的几个资料网站

    菜鸟教程 https://www.runoob.com/python3/python3-tutorial.html https://www.runoob.com/python/python-tutor ...

  5. Django学习路

    1.脚本不能随便运行,没准 linux 运行完就上不去了 2.pip 在 linux 上 写 pip3 同理 python 写为 python3 3.在 pycharm 上安装库之后,在命令提示符中依 ...

  6. PHP array_reverse() 函数

    实例 返回翻转顺序的数组: <?php $a=array("a"=>"Volvo","b"=>"BMW" ...

  7. PHP fseek() 函数

    定义和用法 fseek() 函数在打开的文件中定位. 该函数把文件指针从当前位置向前或向后移动到新的位置,新位置从文件头开始以字节数度量. 如果成功该函数返回 0,如果失败则返回 -1.请注意,移动到 ...

  8. C/C++编程笔记:C++入门知识丨认识C++面向过程编程的特点

    一. 本篇要学习的内容和知识结构概览 二. 知识点逐条分析 1. 使用函数重载 C++允许为同一个函数定义几个版本, 从而使一个函数名具有多种功能, 这称之为函数重载. 像这样: 虽然函数名一样, 但 ...

  9. zabbix配置钉钉机器人告警

    目录 zabbix配置钉钉机器人告警 1. 在钉钉中创建群聊,在群里面添加自定义机器人 2. 配置钉钉告警脚本 3. 配置脚本告警 3.1 创建媒介 3.2 为用户添加对应媒介 3.3 创建动作 4. ...

  10. Jenkins总结1-部署jenkins

    1. 介绍 jenkins是一个广泛用于持续构建的可视化web工具,持续构建说得更直白点,就是各种项目的"自动化"编译.打包.分发部署.jenkins可以很好的支持各种语言(比如: ...