一个开放的,可交互的由开发者制定的 JavaScript Promise 标准。

一个 Promise 代表一个异步操作的最终结果。与 Promise 交互的主要方式是通过它的 then 方法,该 then 方法注册了两个回调函数,用来接收 Promise 的最终结果或者导致 Promise 不能 fulfilled(已完成) 的原因。

本规范详细的列出 then 方法的行为,为所有符合 Promises/A+ 规范的 Promise 提供了一个可互操作的基础来定义 then 方法。因此本规范是稳定的。尽管 Promise/A+ 组织可能会偶尔地通过一些较小的且向后兼容的修订,来解决新发现的一些边界情况。如果要进行大规模或者不兼容的更新,我们一定会经过仔细的考虑、讨论和测试。

从历史上来说,Promises/A+ 规范实际上是把之前 Promises/A规范中的建议变成了标准:扩展了原有规范约定俗成的行为,并删减了原规范的一些特例情况和有问题的部分

最后 Promises/A+ 规范不设计如何创建、解决和拒绝 promise,而是专注于提供一个可交互操作的 then 方法。未来在其他相关规范中可能会提及。

1、术语

  1. promise” 是一个拥有 then 方法的 对象或者函数,它的行为符合本规范
  2. thenable” 是一个定义了 then 方法的对象和函数
  3. 值(“value”) 是任何 JavaScript 的合法值 (包括 undefined, thenable, 或者 promise).
  4. 异常(“exception”) 是使用 throw 抛出的一个值
  5. 原因(“reason”)是一个 promise 的拒绝原因

2、要求

2.1、Promise 的状态

一个 Promise 的当前状态必须是以下三种状态中的一种:等待(pending),完成(fulfilled)和拒绝(rejected

  1. 当一个promise处于等待状态:

    1. 可以迁移到完成状态或者拒绝状态中的任意一个
  2. 当一个 promise 处于完成状态
    1. 一定不能再迁移到其他状态
    2. 必须有一个值(value),而且一定不能再改变
  3. 当一个 promise 处于拒绝状态
    1. 一定不能再迁移到其他状态
    2. 必须有一个原因(reason),而且一定不能再改变

这里,“一定不能改变” 意味着 恒等 (例如 ===),但是并不意味着更深层次的不可变。

2.2、Then 方法

一个 promise 必须提供一个 then 方法,来访问它当前的最终结果或者原因
一个 promisethen 方法接收2个参数:
promise.then(onFulfilled,onRejected)

  1. onFulfilledonRejected 都是可选参数:

    1. 如果 onFulfilled 不是函数,那它必须被忽略
    2. 如果 onRejected 不是函数,那它必须被忽略
  2. 如果 onFulfilled 是一个函数:
    1. 它必须在 promise 状态变成完成(fulfilled)状态之后才会调用,并且promise的值是第一个参数
    2. 它一定不能在 promise 是完成(fulfilled)状态之前被调用
    3. 它一定不能被调用超过1次
  3. 如果 onRejected 是一个函数
    1. 它必须在 promise状态变成拒绝(rejected)之后才会调用,并且promise的原因是第一个参数
    2. 它一定不能在 promise 是拒绝(rejected)状态之前被调用
    3. 它一定不能被调用超过1次
  4. onFulfilledonRejected 只有在执行上下文栈仅包含平台代码的时候才会被调用 [3.1].
  5. onFulfilledonRejected 必须当作函数调用(例如,没有 this值) [3.2]
  6. 同一个 promisethen 方法可以多次调用
    1. promise是完成(fulfilled)状态,所有相应的onFulfilled 回调必须按照他们初始调用then方法的顺序执行
    2. promise是拒绝(rejected)状态,所有相应的onFulfilled 回调必须按照他们初始调用then方法的顺序执行.
      7.then 方法必须返回一个promise对象 [3.3].
      promise2 = promise1.then(onFulfilled,onRejected);
    3. 如果 onFulfilled 或者 onRejected 返回一个值 x,则运行下面的 Promise 解决过程:[[Resolve]](promise2, x)
    4. 如果onFulfilled 或者onRejected 抛出一个异常 e, promise2 必须以 e 为原因被拒绝.
    5. 如果 onFulfilled 不是函数,并且 promise1 是完成状态,那么promise2必须以promise1同样的值完成.
    6. 如果 onReject 不是函数,并且 promise1 是拒绝状态,那么promise2必须以promise1同样的值拒绝.

2.3、Promise 解决过程

Promise 的解决过程是一个抽象操作,需要一个 promise 和一个值来作为输入,我们将其表示为[[Resolve]](promise, x)。如果 x 有 then 方法且看上去像一个 Promise ,那它会尝试让 promise 接收x的状态,否则就用x的值来完成(fulfilled) promise。

这种thenable的特性使得 Promise 的实现更具有通用性:只要其暴露出一个遵循 Promise/A+ 协议的 then 方法即可;这同时也使遵循 Promise/A+ 规范的实现可以与那些不太规范但可用的实现能良好共存。

要运行[[Resolve]](promise, x),需要执行如下步骤:

  1. 如果 promisex 指向同一个对象,那用TypeError为原因拒绝promise
  2. 如果x是一个promise,那就让 promise 接受x的状态 [3.4]:
    1. 如果xpending状态,那promise必须保持pending状态直到x变成完成(fulfilled)或者拒绝(rejected
    2. 如果x是完成态fulfilled, 那让promise 用同样的值(value)完成.
    3. 如果x是拒绝态rejected, 那让promise 用同样的原因(reason)拒绝
  3. x为对象或者函数,
    1. x.then 赋值给 then. [3.5]
    2. 如果检索属性 x.then 导致抛出了一个异常 e,用 e 作为原因拒绝 promise
    3. 如果then是一个函数,用x作为this调用它,第一个参数是 resolvePromise, 第二个参数是rejectPromise:
      1. 如果resolvePromise被一个值y调用,执行[[Resolve]](promise, y).
      2. 如果 rejectPromise 以原因 r为参数被调用,则以原因r拒绝 promise
      3. 如果 resolvePromiserejectPromise 都被调用,或者被同一参数调用了多次,则优先采用第一次调用并剩下的调用都会被忽略
      4. 如果调用抛出异常 e
        1. 如果 resolvePromise 或者 rejectPromise 已经被调用过了,那忽略它
        2. 用异常e为原因拒绝promise
    4. 如果then不是一个函数,用x完成promise
  4. 如果x不是一个对象或者数组,用x完成promise

如果一个 promise 被一个循环的 thenable 链中的对象完成,而 [[Resolve]](promise, thenable)的递归性质又使得其被再次调用,根据上面的算法将会导致无限递归。规范中并没有强制要求处理这种情况,但也鼓励实现者检测这样的递归是否存在,若检测到存在则用一个可识别的 TypeError 为原因来拒绝 promise[3.6]。

3、注释

  1. 这里的平台代码是指引擎、环境以及 promise 的实施代码。在实践中,要确保 onFulfilledonRejected 两个参数异步执行,并且应该在 then方法被调用的那一轮事件循环之后的新执行栈中执行。这可以用如 setTimeoutsetImmediate这样的“宏任务”机制实现,或者用如MutationObserverprocess.nextTick 这样的“微任务”机制实现。由于 promise 的实施代码本身就是平台代码,故代码自身在处理在处理程序时可能已经包含一个任务调度队列
  2. 严格模式下,它们中的this将会是undefined;在非严格模式,this将会是全局对象
  3. 假如实现满足所有需求,可以允许 promise2 === promise1。每一个实现都应该记录是否能够产生promise2 === promise1 以及什么情况下会出现 promise2 === promise1
  4. 总的来说,只有x来自于当前实现,才知道它是一个真正的promise。这条规则允许那些特例实现采用符合已知要求的Promise的状态
  5. 这个程序首先存储x.then的引用,之后测试和调用那个引用,这样避免了多次访问x.then属性。这种预防措施确保了该属性的一致性,因为访问者属性的值可能在俩次检索之间发生变化
  6. 实现不应该在thenable链的深度上做任意限制,并且假设超过那个任意限制将会无限递归。只有真正的循环才应该引发一个TypeError;如果遇到一个无限循环的thenable,永远执行递归是正确的行为

Promises/A+ 规范相关推荐

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

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

  2. Promises/A+规范中文翻译

    翻译: https://promisesaplus.com/ Javascript Promise是一个全面.通用的开放标准,由开发者指定,为开发者参考. Promise代表异步操作的最终结果.与pr ...

  3. [实践系列]Promises/A+规范

    前言 [实践系列] 主要是让我们通过实践去加深对一些原理的理解. 实践系列-前端路由 实践系列-Babel原理 有兴趣的同学可以关注 实践系列 . 求star求follow~ 什么是Promise ? ...

  4. 写一个符合 Promises/A+ 规范并可配合 ES7 async/await 使用的 Promise

    原文地址 从历史的进程来看,Javascript 异步操作的基本单位已经从 callback 转换到 Promise.除了在特殊场景使用 stream,RxJs 等更加抽象和高级的异步数据获取和操作流 ...

  5. Promises/A+规范(中文翻译)

    文章目录 Promises/A+规范(中文翻译) 1. 术语 2. 必要条件 2.1 Promise 的状态 2.2 Then 方法 2.3 Promise 解决过程 3. 注释 4. 参考 Prom ...

  6. promise 全网最详解释,包括各方法和手动实现Promises/A+ 规范(1)

    1.Promise 的含义 作为 Modern JavaScript 基础设施的一部分,Promises 对前端开发者而言异常重要.它是 async/await 语法的基础,是 JavaScript ...

  7. 100 行代码实现 Promises/A+ 规范

    说明 本文转载自[工业聚]:https://mp.weixin.qq.com/s/qdJ0Xd8zTgtetFdlJL3P1g 源码:https://github.com/Lucifier129/pr ...

  8. 跟着 Event loop 规范理解浏览器中的异步机制

    原文发自我的 GitHub blog,欢迎关注 前言 我们都知道 JavaScript 是一门单线程语言,这意味着同一事件只能执行一个任务,结束了才能去执行下一个.如果前面的任务没有执行完,后面的任务 ...

  9. Koa / Co / Bluebird or Q / Generators / Promises / Thunks 的相互关系

    经常游荡在 SO 的我总能发现许多好问题和好答案.它们的"好"不仅仅在于知识的价值,更可贵之处在于如何表达:如何"提问"/如何"回答".不久 ...

最新文章

  1. Boost Asio总结(7)class strand
  2. FileInputStream和FileOutputStream实现任何文件类型的拷贝
  3. 【Linux】一步一步学Linux——unalias命令(206)
  4. LFS(Linux From Scratch)学习
  5. Python检测U盘插入、自动复制文件并写入新文件
  6. no python application found_为什么我会得到“uWSGI Error Python application not found”?
  7. Structure from Motion综述
  8. Ubuntu安装时,下载太慢怎么办
  9. LINUX FFMPEG编译详细过程记录(最全)
  10. 用R语言进行数据可视化的综合指南(一)
  11. python制作奖状,从excel表格中导出数据,取前20名,做成png奖状,再放入ppt中
  12. 7天刷完剑指offer(一)
  13. Linux下线程经典问题(生产者消费者问题,哲学家问题...)
  14. Moive-Pages
  15. vue cli4接入环信webIM
  16. 【补作业】msp430单片机(一)控制LED灯的亮灭
  17. GBase基本查询操作
  18. C#+SQL Server工资管理系统
  19. 打造高安全数字基础设施:中国电子云服务关键行业的宣言
  20. Python算法之旅元组的风暴之最长上升子序列

热门文章

  1. 最新的适合0基础的Java 学习路线,(附视频教程)不仅仅是Javaweb还有大数据哦
  2. CMake中define_property的使用
  3. WHOIS查询(WHOIS lookup)
  4. 服务器中了勒索病毒,升级后的Malox勒索病毒特征,勒索病毒解密数据恢复
  5. 技术文章里那么多的问号与叹号
  6. node 拉取github开源漏洞
  7. 一个离轴抛物面反射镜的几何场追迹
  8. micron 镁光flash mt28g Verilog驱动 FPGA
  9. defined() or define();是什么意思?
  10. 惨痛的春秋航班的经历(春秋的评论,好坏,看完便知)