Promise/A+ 规范翻译

84 阅读3分钟

Promise/A+ 规范主要是针对 then 方法,将来的工作可能会拓展到如何创建 fullfill、reject promise 这些方面

Promise 状态

  • 内部实现只有 3 种状态:pending、fullfilled、rejected
  • state 为 pending 状态时,可以赋值为 fullfilled 或者 rejected 状态
  • state 为 fullfilled / rejected 时
    • promise 不能再赋值为其它状态
    • promise 一定要有不能改变的 value / reason 值 不能再改变

then 方法

promise 必须提供 then 方法来访问最终 value 值或者 reason: promise.then(onFullfilled, onRejected)

  • onFullfilled、onRejected 都是可选的参数
    • 如果它们不是函数,可以忽略下面的逻辑处理了
  • 如果 onFullfilled 是函数
    • 只有当 state 为 fullfilled 时才能调用 onFullfilled 函数,value 是它的第一个参数
    • promise 为 fullfilled 前都不能调用
    • 只能调用一次 onFullfilled
  • 如果 onRejected 是函数
    • 同上,对应的状态为 rejected,以及对应的 value 参数改为 reason
  • onFullfilled、onRejected 只有在执行上下文栈执行以下逻辑时才调用 // 延时绑定的实现
    • 它们是异步执行的,只有在调用then 任务的时候,它们才异步执行的
    • 可以通过宏任务 setTimeout / setImmediate 或者 微任务 MutationObserver / process.nextTick 来实现这个异步操作
  • onFullfilled、onRejected 只能当作函数调用,不能使用 this 值。// 因为 this 指向不明,strict 模式下,this 指向 undefined;非 strict 模式下,this 指向 window 全局对象
  • then 可能会在一个 promise 上执行多次
    • fullfilled 时,onFullfilled 回调函数执行时机必须跟它们相对应的 then 方法顺序一致
    • rejected 时,同上
  • then 必须返回一个 promise // 值穿透 promise2 = promise1.then(onFulfilled, onRejected);
    • 如果 onFullfilled、onRejected 返回的是一个普通值 x,执行以下 Promise Resolution Procedure Resolve(promise, x)
    • 如果 onFullfilled、onRejected 抛出 exception e,统一使用 e 作为错误原因
    • 如果 onFullfilled 不是函数且 promise1 为 fullfilled 时,promise2 也一定是 fullfilled 且 value 值跟 promise fullfilled 的 value 值一样
    • 如果 onRejected 不是函数且 promise1 为 rejected,promise2 也一定为 rejected且值 reason 同 promise1 一样

promise resolution procedure

是一个抽象操作,它使用 promise 和 x 作为参数,可以记作为:function Resolve(promise, x) 。如果 x 是一个 thenable 对象,它会使得 promise 跟 x 的状态是一样的,当然前提是 x 表现得像个 promise 一样,否则它会让 promise 的 fullfilled 得到的 value 值为 x

Resolve(promise, x) 执行如下步骤

  • 如果 promise、x 引用同一个对象,则 promise reject,以 TypeError 作为 reason

  • 如果 x 为 promise,考虑以下几种状态

    • 如果 x state 为 pending,则 promise 会一直为 pending 状态,直到 x 状态为 fullfilled 或者 rejected
    • 当 x state 为 fullfilled,promise 也为 fullfill 状态,且它们有相同的 value 值
    • 当 x state 为 rejected,promise 也为 reject 状态,且它们有相同的 reason
  • 当 x 是一个对象或者函数时

    • 让 then = x.then

    • 如果 x.then 报错,抛出 e 错误,则 promise rejected 且以 e 为 reason

    • 如果 then 是函数。使用 x 来调用它,x 充当 this 角色,第一个参数为 resolvePromise,第2个参数为 rejectPromise。即:then.call(x, resolvePromise, rejectPromise)

      • 当 resolvePromise 传入 y 来调用时,即:Resolve(promise, y)
      • 当 rejectPromise 传入 r 来调用时,promise reject 时需要使用 r 作为参数
      • 如果 resolvePromise、rejectPromise 都调用了,或者多次使用相同参数来调用,则优先第1次调用,其余的调用都可以忽略了
      • 如果 then 抛出异常 e
        • 如果 resolvePromise 或者 rejectPromise 任一调用了,则可以忽略这次异常
        • 否则 promise reject 使用 e 作为 reason
    • x 不是函数或者对象时,promise fullfill 需要使用 x 传参