彻底理解PromiseA+规范

1,810 阅读4分钟

这是我参与11月更文挑战的第14天,活动详情查看:2021最后一次更文挑战

TIP 👉 着意栽花花不发,等闲插柳柳成阴。元·关汉卿《包待制智斩鲁斋郎

前言

Web Component是前端界一直非常热衷的一个领域,用第三方组件化的框架去实现的话,你需要依赖框架本身很多东西,很多时候我们只是简单的几个组件,不是很大,也不是很多,所以为了保证组件的`轻量,简单`,其实这个时候我们并不想采用第三方的框架。

PromiseA+规范

讲解PromiseA+规范前, 咱们先来了解一下这些术语, 以便在后续提到的时候有明确且统一的概念.

术语

  1. promise 是一个有then方法的对象或者是函数,行为遵循本规范
  2. thenable 是一个有then方法的对象或者是函数
  3. value 是promise状态成功时的值,也就是resolve的参数, 包括各种数据类型, 也包括undefined/thenable或者是 promise
  4. reason 是promise状态失败时的值, 也就是reject的参数, 表示拒绝的原因
  5. exception 是一个使用throw抛出的异常值

规范

接下来分几部分来讲解PromiseA+规范.

Promise States

promise应该有三种状态. 要注意他们之间的流转关系.

  1. pending

    1.1 初始的状态, 可改变. 1.2 一个promise在resolve或者reject前都处于这个状态。 1.3 可以通过 resolve -> fulfilled 状态; 1.4 可以通过 reject -> rejected 状态;

  2. fulfilled

    2.1 最终态, 不可变. 2.2 一个promise被resolve后会变成这个状态. 2.3 必须拥有一个value值

  3. rejected

    3.1 最终态, 不可变. 3.2 一个promise被reject后会变成这个状态 3.3 必须拥有一个reason

Tips: 总结一下, 就是promise的状态流转是这样的

pending -> resolve(value) -> fulfilled pending -> reject(reason) -> rejected

then

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

promise.then(onFulfilled, onRejected)
  1. 参数要求

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

  2. onFulfilled 特性

    2.1 在promise变成 fulfilled 时,应该调用 onFulfilled, 参数是value 2.2 在promise变成 fulfilled 之前, 不应该被调用. 2.3 只能被调用一次(所以在实现的时候需要一个变量来限制执行次数)

  3. onRejected 特性

    3.1 在promise变成 rejected 时,应该调用 onRejected, 参数是reason 3.2 在promise变成 rejected 之前, 不应该被调用. 3.3 只能被调用一次(所以在实现的时候需要一个变量来限制执行次数)

  4. onFulfilled 和 onRejected 应该是微任务

    这里用queueMicrotask来实现微任务的调用.

  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 onFulfilled 或 onRejected 执行的结果为x, 调用 resolvePromise( 这里大家可能难以理解, 可以先保留疑问, 下面详细讲一下resolvePromise是什么东西 ) 6.2 如果 onFulfilled 或者 onRejected 执行时抛出异常e, promise2需要被reject 6.3 如果 onFulfilled 不是一个函数, promise2 以promise1的value 触发fulfilled 6.4 如果 onRejected 不是一个函数, promise2 以promise1的reason 触发rejected

  7. resolvePromise

    resolvePromise(promise2, x, resolve, reject)
    

    7.1 如果 promise2 和 x 相等,那么 reject TypeError

    7.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.
         
    

    7.3 如果 x 是一个 object 或者 是一个 function

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

    这段描述看起来非常的空洞乏味, 最重要的是看不懂! 所以待会实现代码的时候, 同学们注意一下resolvePromise函数具体的实现, 结合代码来看会好很多.

样式这块就先不放了

「欢迎在评论区讨论」

希望看完的朋友可以给个赞,鼓励一下