【翻译】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
必须处于pending
、fulfilled
或rejected
三种状态之一。
2.1.1. 当处于pending
状态, 一个promise:
- 2.1.1.1 可能转变为
fulfilled
或rejected
状态.
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
)表示一旦变为fulfilled
或rejected
状态,结果将不会再变更
2.2 then
方法
一个promise
必须提供一个then
方法来访问其当前或最终的值,或者原因。
promise
的then
方法接受两个参数:
promise.then(onFulfilled, onRejected)
2.2.1 onFulfilled
和onRejected
都是可选参数
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 onFulfilled
和onRejected
只有在执行环境堆栈仅包含平台代码时才能被调用。3.1
2.2.5 onFulfilled
和onRejected
必须作为普通函数调用(例如,没有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 如果
onFulfilled
或onRejected
返回一个值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 如果promise
和x
指向同一对象,那么用TypeError
作为原因拒绝promise
。
2.3.2 如果x
是一个promise,则使用它的状态:
2.3.2.1 如果
x
是pending,则promise必须保留pending直到x
变为fulfilled或rejected2.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.52.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 如果
resolvePromise
和rejectPromise
都被调用,或者使用相同参数多次调用,则优先使用第一个调用,任何其他调用将被忽略。2.3.3.3.4 如果调用
then
抛出一个异常e
- 2.3.3.3.4.1 如果
resolvePromise
或rejectPromise
已经被调用,则忽略它 - 2.3.3.3.4.2 否则,使用
e
作为原因拒绝promise
- 2.3.3.3.4.1 如果
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调用的事件循环之后进入,并且使用的是新的堆栈异步执行onFulfilled
和onRejected
。可以使用"宏任务"(macro-task
)机制(如setTimeout或setImmediate)或"微任务"(micro-task
)机制(如MutationObserver或process.nextTick)来实现。由于promise的实现被视为平台代码,因此在调用的处理程序中,它本身可能包含一个任务调度队列(task-scheduling queue
)或"跳板"(trampoline
,蹦床)。
3.2
在严格模式中,函数内部的this
是undefined
;在松散模式中,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+规范的更多相关文章
- 前端翻译:Promises/A+规范
原文地址:https://promisesaplus.com/ 本篇为原文翻译+个人理解,若有谬误请各位指正,谢谢. 尊重原创,转载请注明来自:http://www.cnblogs.com/fsjoh ...
- CommonJS Promises/A规范
本文来自四火哥的翻译 CommonJS是一组javascript编程规范,而promise是其中之一. 简而言之,promises是一种令代码的异步行为变得更加优雅的软件抽象.在基本的定义中,代码可能 ...
- JavaScript中Promises/A+规范的实现
Promises是一种异步编程模型,通过一组API来规范化异步操作,这样也能够让异步操作的流程控制更加容易. 下面的代码是假设执行一个异步队列,每一项都会使用上一项返回的数据: function ne ...
- JS魔法堂:剖析源码理解Promises/A规范
一.前言 Promises/A是由CommonJS组织制定的异步模式编程规范,有不少库已根据该规范及后来经改进的Promises/A+规范提供了实现 如Q, Bluebird, when, rsvp. ...
- 一起学习造轮子(一):从零开始写一个符合Promises/A+规范的promise
本文是一起学习造轮子系列的第一篇,本篇我们将从零开始写一个符合Promises/A+规范的promise,本系列文章将会选取一些前端比较经典的轮子进行源码分析,并且从零开始逐步实现,本系列将会学习Pr ...
- 对 Promises/A+ 规范的研究 ------引用
作为 Modern JavaScript 基础设施的一部分,Promises 对前端开发者而言异常重要.它是 async/await 语法的基础,是 JavaScript 中处理异步的标准形式.并且, ...
- Promises/A+规范
为什么需要异步编程方式 一个函数执行之后,在它后面顺序编写的代码中,如果能够直接使用它的返回结果或者它修改之后的引用参数,那么我们通常认为该函数是同步的. 如果一个函数的执行结果或者其修改的引用参数, ...
- [iOS翻译]Cocoa编码规范
简介: 本文整理自Apple文档<Coding Guidelines for Cocoa>.这份文档原意是给Cocoa框架.插件及公共API开发者提供一些编码指导,实质上相当于Ap ...
- [JavaScript] promise概述
promise promise 是 es6 提出的一个异步解决方案,比传统回调事件的写法更加合理更加强大,主要还是优雅 promise 有 pending(等待中),fulfilled(已成功),re ...
随机推荐
- xss原理绕过防御个人总结
xss原理 xss产生的原因是将恶意的html脚本代码插入web页面,底层原理和sql注入一样,都是因为js和php等都是解释性语言,会将输入的当做命令执行,所以可以注入恶意代码执行我们想要的内容 x ...
- MongoDB基本使用方法
mongo与关系型数据库的概念对比,区分大小写,_id为主键. 一.数据库操作 >show dbs或者show databases #查看所有数据库 >use dbname #创 ...
- JavaFX让UI更美观-CSS样式
相对于Swing来说,JavaFX在UI上改善了很多,不仅可以通过FXML来排版布局界面,同时也可以通过CSS样式表来美化UI. 其实在开发JavaFX应用的时候,可以将FXML看做是HTML,这样跟 ...
- RectTransform的localPosition与anchoredPosition(3D)的区别
RectTransform继承自Transform,用于描述矩形的坐标(Position),尺寸(Size),锚点(anchor)和中心点(pivot)等信息,每个2D布局下的元素都会自动生成该组件. ...
- 网络滴神,TCP!
TCP在网络协议(网络协议见这篇文章)中的重要性就相当于女朋友对于程序员的重要一样,这么说你应该知道有多重要了吧. 1. 三次握手 TCP在进行数据的传输之前必须先建立连接,建立之后才能进行数据的传 ...
- 4.9 省选模拟赛 划分序列 二分 结论 树状数组优化dp
显然发现可以二分. 对于n<=100暴力dp f[i][j]表示前i个数分成j段对于当前的答案是否可行. 可以发现这个dp是可以被优化的 sum[i]-sum[j]<=mid sum[i] ...
- Linux的VMWare中Centos7查看文件内容命令 (more-less-head-tail)
一.More分页查看文件 more 命令类似 cat ,不过会以一页一页的形式显示,更方便使用者逐页阅读, 而最基本的指令就是按空白键(space)就往下一页显示, 按 b 键就会往回(back)一页 ...
- nvidia-smi:控制您的GPU
翻译 https://www.microway.com/hpc-tech-tips/nvidia-smi_control-your-gpus/ 大多数用户知道如何检查其CPU的状态,查看多少系统内存 ...
- JavaScript动画实例:炸开的小球
1.炸开的小球 定义一个小球对象类Ball,它有6个属性:圆心坐标(x,y).小球半径radius.填充颜色color.圆心坐标水平方向的变化量speedX.圆心坐标垂直方向的变化量speedY. B ...
- Python使用socketServer包搭建简易服务器过程详解
官方提供了socketserver包去方便我们快速的搭建一个服务器框架. 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很多已经做案例的 ...