promise A+ 规范梳理

181 阅读4分钟

一、 什么是 Promise

Promise 对象用于表示一个异步操作的最终完成 (或失败)及其结果值。是目前比较流行Javascript异步编程解决方案之一。

二、promise A+ 规范

参考 promise A+ 官方,对promise A+规范做个翻译整理。

1.术语

  • 1.1. promise: 是一个拥有then方法的对象或函数,行为符合这个规范。
  • 1.2. thenable: 是一个then方法的对象或函数。
  • 1.3. value: 是promise状态成功的时的值(resolve参数),包括各种数据类型(如undefined,thenable,promise等)。
  • 1.4. exception: 是一个使用throw语句抛出的一个值
  • 1.5. reason: 是promise状态失败的值(reject参数),表示为什么被拒绝

2.要求

2.1 Promise 状态

promise 的当前状态必须是以下三种状态中的一种:pending,fulfilledrejected ,要注意他们之间的流转关系.

  1. pending 等待态

    是初始的状态,在resolvereject前都是这个状态。可改变为 fulfilled 状态 和 rejected 状态。

  2. fulfilled 解决态

    是最终态,不可变promiseresolve后会变成这个状态。必须有一个不能改变的值 value

  3. rejected 拒绝态

    是最终态,不可变promisereject后会变成这个状态。必须有一个不能改变的值 reason

2.2 then 方法

promise应该提供一个then方法, 用来访问最终的结果(无论是value还是reason).

promisethen方法接受俩个参数:

promise.then(onFulfilled, onRejected)
  1. onFulfilledonRejected都是可选的参数

    1.1 如果 onFulfilled 不是函数类型, 必须被忽略.

    1.2 如果 onRejected 不是函数类型, 必须被忽略.

  2. 如果 onFulfilled是函数,它的特性:

    2.1 在promise变成 fulfilled 后调用 onFulfilledvalue 作为它的第一个参数

    2.2 在promise变成 fulfilled 之前,不能被调用

    2.3 只能被调用一次

  3. 如果 onRejected是函数,它的特性

    3.1 在promise变成 rejected 后调用 onRejected, reason 作为他的第一个参数

    3.2 在promise变成 rejected 之前, 不能被调用

    3.3 只能被调用一次

  4. onFulfilledonRejected 调用时机和调用要求

    4.1 onFulfilled 和 onRejected 只有在执行环境堆栈仅包含平台代码时才可被调用(onFulfilledonRejected应该是微任务)

    4.2 onFulfilled 和 onRejected 必须被作为函数调用(即没有 this 值)

  5. then方法可以被调用多次

    5.1 promise 状态变成 fulfilled 后,所有的 onFulfilled 回调均按照初始调用顺序执行(即按照then的顺序执行,实现时用一个数组来存放多个onFulfilled的回调)

    5.2 promise状态变成 rejected 后,所有的 onRejected 回调均按照初始调用顺序执行(即按照then的顺序执行,实现时用一个数组来存放多个onRejected的回调)

  6. then方法 必须返回一个promise

    promise2 = promise1.then(onFulfilled, onRejected);
    

    6.1 onFulfilledonRejected 执行返回的结果为x, 则运行下面的 Promise 解决过程 [[Resolve]](promise2, x)(这里我们简述为:调用 resolvePromise)

    6.2 如果 onFulfilled 或者 onRejected 执行时抛出异常 e, promise2必须被reject,并返回 reason 作为 e

    6.3 如果 onFulfilled 不是一个函数,并且promise1执行fulfilledpromise2promise1value 触发fulfilled

    6.4 如果 onRejected 不是一个函数,并且promise1执行rejectedpromise2promise1reason 触发rejected

2.3. Promise 解决过程(上面提到的 resolvePromise)

[[Resolve]](promise2, x)

// 我们自己实现写成下面这样
resolvePromise(promise2, x, resolve, reject)
  1. 如果 promise2x 引用同一个对象,那么 rejectpromise 会并用TypeError作为reason

  2. 如果 x 是一个 promsie

    如果 x 处于 pending态,那么promise必须要保持pending,直到 x 变成 fulfilled or rejected.
    如果 x 被 fulfilled, fulfill promise with the same value.
    如果 x 被 rejected, reject promise with the same reason.
        
    
  3. 如果 xobject 或者 function

    3.1 把 x.then 赋值给 thenlet then = x.then

    3.2 如果 取 x.then 抛出错误e,那么 reject promise with e as the reason.

    3.3 如果 then 是一个函数,将 x 作为函数的作用域 this 调用之。

    then.call(x, resolvePromiseFn, rejectPromise)
    
     1 resolvePromiseFn 的 入参是 y, 执行 resolvePromise(promise2, y, resolve, reject);
     2 rejectPromise 的 入参是 r, reject promise with r.
     3 如果 resolvePromise 和 rejectPromise 都调用了,那么第一个调用优先,后面的调用忽略。
     4 如果调用then抛出异常e 
         如果 resolvePromise 或 rejectPromise 已经被调用,那么忽略
         则,reject promise with e as the reason
     5 如果 then 不是一个函数. fulfill promise with x.
    

参考文献