Promise/A+规范

Promise表示一个异步操作的最终结果。与Promise最主要的交互方法是通过将函数传入它的then方法从而获取得Promise最终的值或Promise最终最拒绝(reject)的原因。

1. 术语

promise是一个包含了兼容promise规范then方法的对象或函数,
thenable 是一个包含了then方法的对象或函数。
value 是任何Javascript值。 (包括 undefined, thenable, promise等).
exception 是由throw表达式抛出来的值。
reason 是一个用于描述Promise被拒绝原因的值。

2. 要求

2.1 Promise状态

一个Promise必须处在其中之一的状态:pending, fulfilled 或 rejected.

  • 如果是pending状态,则promise:

    • 可以转换到fulfilled或rejected状态。
  • 如果是fulfilled状态,则promise:

    • 不能转换成任何其它状态。
    • 必须有一个值,且这个值不能被改变。
  • 如果是rejected状态,则promise可以:

    • 不能转换成任何其它状态。
    • 必须有一个原因,且这个值不能被改变。

”值不能被改变”指的是其identity不能被改变,而不是指其成员内容不能被改变。

2.2 then 方法

一个Promise必须提供一个then方法来获取其值或原因。
Promise的then方法接受两个参数:

jspromise.then(onFulfilled, onRejected)
  1. onFulfilledonRejected 都是可选参数:

    1. 如果onFulfilled不是一个函数,则忽略之。
    2. 如果onRejected不是一个函数,则忽略之。
  2. 如果onFulfilled是一个函数:

    1. 它必须在promise fulfilled后调用, 且promise的value为其第一个参数。
    2. 它不能在promise fulfilled前调用。
    3. 不能被多次调用。
  3. 如果onRejected是一个函数,

    1. 它必须在promise rejected后调用, 且promise的reason为其第一个参数。
    2. 它不能在promise rejected前调用。
    3. 不能被多次调用。
  4. onFulfilledonRejected 只允许在 execution context 栈仅包含平台代码时运行. [3.1].
  5. onFulfilledonRejected 必须被当做函数调用 (i.e. 即函数体内的 thisundefined). [3.2]
  6. 对于一个promise,它的then方法可以调用多次.

    1. promise fulfilled后,所有onFulfilled都必须按照其注册顺序执行。
    2. promise rejected后,所有OnRejected都必须按照其注册顺序执行。
  7. then 必须返回一个promise [3.3].

    jspromise2 = promise1.then(onFulfilled, onRejected);
    
    1. 如果onFulfilledonRejected 返回了值x, 则执行Promise 解析流程[[Resolve]](promise2, x).
    2. 如果onFulfilledonRejected抛出了异常e, 则promise2应当以ereason被拒绝。
    3. 如果 onFulfilled 不是一个函数且promise1已经fulfilled,则promise2必须以promise1的值fulfilled.
    4. 如果 OnReject 不是一个函数且promise1已经rejected, 则promise2必须以相同的reason被拒绝.

2.3 Promise解析过程

Promise解析过程 是以一个promise和一个值做为参数的抽象过程,可表示为[[Resolve]](promise, x). 过程如下;

  1. 如果promisex 指向相同的值, 使用 TypeError做为原因将promise拒绝。
  2. 如果 x 是一个promise, 采用其状态 [3.4]:

    1. 如果x是pending状态,promise必须保持pending走到x fulfilled或rejected.
    2. 如果x是fulfilled状态,将x的值用于fulfill promise.
    3. 如果x是rejected状态, 将x的原因用于reject promise..
  3. 如果x是一个对象或一个函数:

    1. then 赋为 x.then. [3.5]
    2. 如果在取x.then值时抛出了异常,则以这个异常做为原因将promise拒绝。
    3. 如果 then 是一个函数, 以xthis调用then函数, 且第一个参数是resolvePromise,第二个参数是rejectPromise,且:

      1. resolvePromise 被以 y为参数调用, 执行 [[Resolve]](promise, y).
      2. rejectPromise 被以 r 为参数调用, 则以r为原因将promise拒绝。
      3. 如果 resolvePromiserejectPromise 都被调用了,或者被调用了多次,则只第一次有效,后面的忽略。
      4. 如果在调用then时抛出了异常,则:

        1. 如果 resolvePromiserejectPromise 已经被调用了,则忽略它。
        2. 否则, 以e为reason将 promise 拒绝。
    4. 如果 then不是一个函数,则 以x为值fulfill promise
  4. 如果 x 不是对象也不是函数,则以x为值 fulfill promise

补充

英文原文地址:http://promisesaplus.com
若要了解文中每一条规则,则参阅其测试仓库:https://github.com/promises-aplus/promises-tests/tree/master/lib/tests


负能量职业打码师

1.5k 声望
98 粉丝
0 条评论
推荐阅读
redux中的middleware
其中applyMiddleware(...)是一个enhancer。enhancer在redux中的作用会代理createStore方法返回具有增强效果的store.

ssnau阅读 1.7k

Promise: 异步编程的理解和使用
JavaScript 中,Promise 的流行是得益于 jQuery 的方法 jQuery.Deferred(),其他也有一些更精简独立的 Promise 库,例如:Q、When、Bluebird。

后除2阅读 789

百万并发场景中倒排索引与位图计算的实践
Promise时效控单系统作为时效域的控制系统,在用户下单前、下单后等多个节点均提供服务,是用户下单黄金链路上的重要节点;控单系统主要逻辑是针对用户请求从规则库中找出符合条件的最优规则,并将该规则的时效控...

京东云开发者1阅读 366

封面图
从 await-to-js 到 try-run-js
之前在做 code review 时候发现有同事使用 try catch 包装了一堆异步代码,于是个人就觉得很奇怪,难道不应该只 catch 可能出问题的代码吗?同事告诉我说 try catch 太细的话会出现内外作用域不一致,需要提前声...

jump__jump阅读 991

Promise基础(消化错误和抛出错误)
在这两个回调中 return xxx ,相当于调用 return new Promise((resolve) => resolve(xxx));

uccs1阅读 872

alicdn边缘节点不稳定导致页面崩溃问题
某工作日,线上某用户向客服专员反馈没法正常访问“查看报价页面”,页面内容没有呈现。客服专员收到反馈后,将问题转交给SRE处理。很奇怪的是,SRE访问生产环境“查看报价页面”显示正常,为了进一步分析定位问题,S...

记得要微笑阅读 743

php 实现 Promise.all 和 Promise.race
测试 {代码...} 结果 {代码...} 实现 {代码...}

何一鸣阅读 641

负能量职业打码师

1.5k 声望
98 粉丝
宣传栏