前端翻译:Promises/A+规范
原文地址:https://promisesaplus.com/
本篇为原文翻译+个人理解,若有谬误请各位指正,谢谢。
尊重原创,转载请注明来自:http://www.cnblogs.com/fsjohnhuang/p/4139172.html ^_^肥仔John
一个可靠的可共同协作的JavaScript Promise开放标准
promise代表一个异步操作的最终结果。主要通过promise的then方法订阅其最终结果的处理回调函数,和订阅因某原因无法成功获取最终结果的处理回调函数。
本说明将详述then方法的行为特点,符合Promise/A+规范的promise实现均以then方法为交互核心。Promises/A+组织会因新发现的问题以向后兼容的方式修改规范,且每次修改均会经过严格的考虑、讨论和测试,因此Promises/A+规范相对来说还是比较稳定的。
Promises/A+是在Promises/A的基础上对原有规范进行修正和增强。
最后,本说明并不涉及如何创建、fulfill或reject promises,而是着重介绍then方法。将来或许在其他说明中涉及这些内容。
1. 术语
1.1. "promise"拥有then方法且符合Promises/A+标准的对象。
1.2. "thenable"拥有thne方法的对象。
1.3. "value"合法的JavaScript对象(包括undefined,thenable对象,promise对象)。
1.4. "exception"通过throw语句抛出的值。
1.5. "reason"合法的JavaScript对象,表示promise状态转换为rejected的原因。
2. 需求
2.1. Promise状态
promise状态为pending,fulfilled和rejected中的其中一种。
2.1.1. 当promise状态为pending时:
2.1.1.1. promise的状态可以转换为fulfilled或rejected。
2.1.2. 当promise状态为fulfilled时:
2.1.2.1. 无法转换为其他状态。
2.1.2.2. 必须有一个不可改变的值作为onFulfilled事件处理函数的入参
2.1.3. 当promsie状态为rejected时:
2.1.2.1. 无法转换为其他状态。
2.1.2.2. 必须有一个不可改变的值作为onRejected事件处理函数的入参
上述不可改变的值是指value或reason变量所存储的值或地址不变,而不是指地址所指向的堆空间内的对象属性等不可变。
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的不可变值将作为 onFulfilled函数 的入参。
2.2.2.2. 在promise状态转换为fulfilled前禁止被调用。
2.2.2.3. 只能被调用一次。
2.2.3. 如果 onRejected 为函数时:
2.2.3.1. 当且仅当promise状态为rejected时才能被调用(晚绑定依然会被调用),并且promise的不可变值将作为 onRejected函数 的入参。
2.2.3.2. 在promise状态转换为rejected前禁止被调用。
2.2.3.3. 只能被调用一次。
2.2.4. onFulfilled 和 onRejected 当且仅当执行上下文栈中仅包含平台代码[3.1]时才执行
2.2.5. onFulfilled 和 onRejected 必须以函数的形式来调用(也就是 this对象 在sloppy模式下为全局对象,strict模式下为undefined)[3.2]
2.2.6. 同一个promise的then方法可被多次调用
2.2.6.1. 当promise状态为fulfilled时,将按调用then方法的顺序执行 onFulfilled函数 。
2.2.6.2. 当promise状态为rejected时,将按调用then方法的顺序执行 onRejected函数 。
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将执行 reject(e) 。
2.2.7.3. 如果 promise1的 onFulfilled 不是函数,那么promise1的不可变值将传递到promise2并作为promise2的不可变值。
2.2.7.4. 如果 promise1的 onRejected不是函数,那么promise1的不可变原因将传递到promise2并作为promise2的不可变原因,并作为promise2的 onRejected 的入参。
2.3. Promise处理过程
Promise处理步骤是对表示形式为 [[Resolve]](promise, x) 的状态事件处理函数的返回值的抽象处理。如果x为thenable对象,由于thanble对象的行为特性类似于一个promise实例,因此让x来设置promise的状态。若x为其他类型则设置promise的状态为fulfilled并且不可变值为x。
[[Resolve]](promise, x) 的处理过程如下:
2.3.1. 如果promise和x指向同一个对象,则将promise的状态转换为rejected并且以TypeError作为不可变原因。
2.3.2. 如果x是一个promise实例,则以x的状态作为promise的状态[3.4]
2.3.2.1. 如果x的状态为pending,那么promise的状态也为pending,直到x的状态变化而变化。
2.3.2.2. 如果x的状态为fulfilled,promise的状态也为fulfilled,并且以x的不可变值作为promise的不可变值。
2.3.2.3. 如果x的状态为rejected,promise的状态也为rejected,并且以x的不可变原因作为promise的不可变原因。
2.3.3. 如果x是对象或函数
2.3.3.1. 将x.then赋值给变量then[3.5]
2.3.3.2. 如果在获取属性x.then时抛出异常,则将promise的状态转换为rejected并且以e作为promise的不可变原因。
2.3.3.3. 如果then为函数类型,则以x作为then函数内部的this指针,以promise的resolvePromise和rejectPromise作为入参调用then函数。
2.3.3.3.1. 如果以y作为入参调用resolvePromise,那么则执行Promise处理过程 [[Resolve]](promise, y) 。
2.3.3.3.2. 如果以r作为入参调用rejectPromise,那么则将promise状态转换为rejected并且以r作为promise的不可变原因。
2.3.3.3.3. resolvePromise和rejectPromise仅有一个能被调用,且仅能调用一次,重复调用均视作无效操作。
2.3.3.3.4. 如果调用then方法抛出异常
2.3.3.4.1. 如果resolvePromise或rejectPromise已经被调用后才抛出异常,则无视。
2.3.3.4.2. 其他情况则将promise状态转换为rejected并且以异常对象e作为promise的不可变原因。
2.3.3.4. 如果then不是函数,则将promise状态转换为fulfilled并且以x作为promise的不可变值。
2.3.4.如果x不是对象或函数,则将promise状态转换为fulfilled并且以x作为promise的不可变值。
假如不断以Promise或thenable作为onFulfilled的返回值,那么就会进入Promise处理过程的死循环中,虽然Promise/A+规范并没有明确规定具体实现需要通过对死循环进行返回TypeError异常的处理,但实现者可以自行考虑该情况的处理方式。[3.6]
3. 备注
3.1. 这里的“平台代码”是指引擎、执行环境和promise实现代码。实际上,是要求 onFulfilled 和 onRejected 函数为异步执行。浏览器可通过 setTimeout 或 setImmediate ,nodejs可通过 MutationObserver 或 process.nextTick 将函数调度到event loop队列中达到异步执行的效果。
3.2. 在strict模式下this指针为undefined,而在sloppy模式下this指针为全局对象。
3.3. 具体实现可允许promise2===promise1,并且需要将promise2===promise1的条件以文档形式标注说明。
3.4. x为真正的promise实例。
3.5. 由于考虑到ES5的getter特性可能会产生副作用,因此在获取x.then属性时,应该形如以下方式,防止多次调用x.then。
var then = x.then;
typeof(then) === 'function' && then.call(x, resolvePromise, rejectPromise)
3.6.具体实现武断地限制Promise处理过程的递归深度,只有真正的死循环才抛出TypeError异常。如果允许无限循环,也是没问题的。
版权所有:Promises/A+组织
前端翻译:Promises/A+规范的更多相关文章
- 【翻译】Promises/A+规范
目录 介绍 译文 1. 术语(Terminology) 2. 要求(Requirements) 2.1 Promise状态 2.2 then方法 2.3 Promise解析程序 3. 注释 3.1 p ...
- CommonJS Promises/A规范
本文来自四火哥的翻译 CommonJS是一组javascript编程规范,而promise是其中之一. 简而言之,promises是一种令代码的异步行为变得更加优雅的软件抽象.在基本的定义中,代码可能 ...
- 一起学习造轮子(一):从零开始写一个符合Promises/A+规范的promise
本文是一起学习造轮子系列的第一篇,本篇我们将从零开始写一个符合Promises/A+规范的promise,本系列文章将会选取一些前端比较经典的轮子进行源码分析,并且从零开始逐步实现,本系列将会学习Pr ...
- 对 Promises/A+ 规范的研究 ------引用
作为 Modern JavaScript 基础设施的一部分,Promises 对前端开发者而言异常重要.它是 async/await 语法的基础,是 JavaScript 中处理异步的标准形式.并且, ...
- JavaScript中Promises/A+规范的实现
Promises是一种异步编程模型,通过一组API来规范化异步操作,这样也能够让异步操作的流程控制更加容易. 下面的代码是假设执行一个异步队列,每一项都会使用上一项返回的数据: function ne ...
- JS魔法堂:剖析源码理解Promises/A规范
一.前言 Promises/A是由CommonJS组织制定的异步模式编程规范,有不少库已根据该规范及后来经改进的Promises/A+规范提供了实现 如Q, Bluebird, when, rsvp. ...
- 团队开发前端VUE项目代码规范
团队开发前端VUE项目代码规范 2018年09月22日 20:18:11 我的小英短 阅读数 1658 一.规范目的: 统一编码风格,命名规范,注释要求,在团队协作中输出可读性强,易维护,风格一致 ...
- Promises/A+规范
为什么需要异步编程方式 一个函数执行之后,在它后面顺序编写的代码中,如果能够直接使用它的返回结果或者它修改之后的引用参数,那么我们通常认为该函数是同步的. 如果一个函数的执行结果或者其修改的引用参数, ...
- web前端开发CSS命名规范参考
做为一个web前端工程师,每天接触HTML.css就像吃饭一样,但是作为一名合作.优秀的web前端工程师,对DIV+CSS命名还是有一定的规范的,本文整理了一份web前端开发中DIV+CSS各种命名规 ...
随机推荐
- HTML5手机APP开发入(4)
HTML5手机APP开发入(4) 课程内容 完成一个自定义的Component用来展现通讯录用户的明细信息如下图 http://bootsnipp.com/snippets/featured/prof ...
- zz 圣诞丨太阁所有的免费算法视频资料整理
首发于 太阁实验室 关注专栏 写文章 圣诞丨太阁所有的免费算法视频资料整理 Ray Cao· 12 小时前 感谢大家一年以来对太阁实验室的支持,我们特地整理了在过去一年中我们所有的原创算法 ...
- 无线局域网络 WIFI/WAPI/WLAN区别浅析
WIFI和WAPI的区别 既然WIFI和WAPI都是WLAN的传输协议,那么两者究竟都有怎样的区别? 首先第一点区别在于,两者的缔造者不一样.WIFI是又国外制定的一个协议,而WAPI是由中国制定的, ...
- 【Android】Android 移动应用数据到SD
[Android]Android 移动应用数据到SD 在应用的menifest文件中指定就可以了,在 <manifest> 元素中包含android:installLocation 属性, ...
- Mac前端抓包小工具Charles4.0下载
链接: https://pan.baidu.com/s/1skPxdNJ 密码: 7iwp 使用方法:安装完主程序后,将dmg包里charles.jar拖至/Applications/Charles. ...
- 安装redis监控
在修改登录中心的时候,数据存储在redis里面,需要对redis进行监控,使用的是Redis-Live 参考文章: http://www.nkrode.com/article/real-time-da ...
- Vmware9.0打开早期版本报错:this virtual machine’s policies are too old to be run by this version of vmware workstation”
VMWare从6.0升级到9.0,打开以前的虚拟机报错如下: “this virtual machine’s policies are too old to be run by this versio ...
- Cocos2dx使用wxsqlite开源加密SQLite3数据库
最近使用wxsqlite加密sqlite3数据库,刚开始折腾好几天,在xcode上一直编译不通过,后来在sqlite3.c找到配置,编译顺利通过,太激动了,哈哈,废话少说!总结一下android和io ...
- leetCode191/201/202/136 -Number of 1 Bits/Bitwise AND of Numbers Range/Happy Number/Single Number
一:Number of 1 Bits 题目: Write a function that takes an unsigned integer and returns the number of '1' ...
- 如何配置ssh免密码登录
[TOC] 如果你在管理一堆unix机器,每次登录都要输入密码是挺烦的事情,一方面为了安全我们一般不会将所有机器的密码都设置成一样,另一方面就算一样每次都输入一遍也很麻烦. 这种情况下我们一般是用ss ...