Promise

116 阅读2分钟

“Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。”

promise规范

今天来写写promise规范

github.com/promises-ap… segmentfault.com/a/119000000…

promise`` 是一个object || function 拥有兼容Promise A+ 的then方法

thenable`` 是一个object || function 里面定义了then属性,typeof then === 'function'

then规范

then(onResolved, onRejected)

  1. 如果onResolved 和 onRejected 不是一个函数,忽视(值穿透)

    • 若typeof onResolved ≠= function 并且 promise1的status=="resolved", 那么promise2要以promise1的value作为改变status为resolved的value
    • 若typeof onRejected ≠= function 并且 promise1的status=="rejected", 那么promise2要以promise1的reason作为改变status为rejected的reason
  2. onResolved 传入promise的value值作为第一个参数 只有在promise的status ="resolved"的状态下执行 只能被调用一次

  3. onRejected 传入promise的reason值作为第一个参数 只有在promise的status ="rejected"的状态下执行 只能被调用一次

  4. then可能被同一个promise调用多次, 执行onResolved或onRejected时要按照传入顺序执行(链式调用)

  5. then必须返回一个新的promise2 ``若onReoslved 或 onRejected 是函数``,x = onResolved(this.data)或x=onRejected(this.reason),然后执行resolvePromise(promise, x) ``若onResolved 或 onRejected执行过程出throw(err), prmoise2以err作为改变状态为rejected的reason

  6. 异步执行onResolved 或 onRejected

resolvePromise规范

resolvePromise(promise, x) 根据x决定promise的状态

  1. x===promise`` 以TypeError为reason reject promise

  2. x instanceof promise`` x.status === "pending", promise保持pending状态直到x改变status为resolved或rejected x.status === "resolved", 以同样的value resolve promise x.status === "rejected", 以同样的reason reject promise

  3. x 是个object || function`` let call = false const then = x.then

    1. 如果检测x.then的过程中,出错err被catch(err),以err为reason,reject promise

    2. 若then ≠function, 以x为value resolve promise

    3. 若then == function, 以x为this执行then then(onResolved(v), onRejected(r))

      1. 执行过程中catch(err), reject(err) promise
      2. 若 onResolved 被执行,onResolved((y)=>{resolvePromsie(y,promsie)}) 若onRejected 被执行, 用r为reason, reject promise then中的onResolved和onRejected只执行第一次的onResolved或onRejected, 其他的忽略,使用call = true控制 例如 then(onResolved, onReject){onResolved(y); onReject(r)}此情况下只有onResolved是 有效的
  4. 若x 不符合上述情况, 以x为value, resolve promise

参考资料: (juejin.cn/post/706966… "juejin.cn/post/706966…