手撕promise

本文详细介绍了Promise A+规范,并通过一个实例解析了Promise的构造和状态转换。从Proxy到Promise的实现,深入探讨了状态管理、then方法的规则以及解决过程。同时,讨论了静态方法如resolve、reject、all和race的实现原理,帮助理解Promise的工作机制。
摘要由CSDN通过智能技术生成

Proxy

vue3.0应用该特性替代Object.defineproperty

解决的痛点:

  1. 监听不到属性的添加和删除
  2. 监听数组索引和长度的变更
  3. 不能支持Map,Set,WeakMap和WeakSet

Promise A+规范

参考文章
Promise/A+翻译
手撕遵循 Promise/A+ 规范的 Promise
手把手教你实现 Promise
MDN

要求

  1. promise状态:Pending,Fulfilled and Rejected

    Pending=>Fulfilled or Rejected

    Fulfilled必须有一个不可改变的值,且不可再转换状态

    Rejected必须有一个不可改变的原因,且不可再转换状态

  2. then方法

    promise必须提供一个then方法以访问它当前或最终的值或被拒绝的原因

    promise.then(onFulfilled,onRejected);
    
    • onFulfilledonRejected都是可选参数,如果不是函数将忽略

    • onFulfilledonRejected如果是函数:

      • 它们必须在promise完成/拒绝后被调用,并且以promise的值/原因作为它的第一个参数
      • promise完成/拒绝前不可调用
      • 仅可调用一次
    • onFulfilledonRejected只有在执行上下文堆栈仅包含平台代码是才可被调用

    • onFulfilledonRejected必须作为函数调用

    • then在相同的promise可以被调用多次

      当promise是完成/拒绝时,相应的回调函数必须按其原始调用的顺序执行

    • then方法必须返回一个promise

      promise2 = promise1.then(onfulfilled,onRejected);
      
      • 如果onFulfilledonRejected返回一个值x,则运行[[Resolve]](promise2,x)

        promise2=new Promise(resolve=>resolve(10)).then(()=>1)
        

        这个例子将会运行[[Resolve]](promise2,1),结果将在下面解决过程分析

      • 如果onFulfilledonRejected抛出一个异常e,则promise2拒绝执行,返回拒因e

      • 如果onFulfilled不是函数且promise1成功执行,promise2必须成功执行并返回相同的值

      • 如果onRejected不是函数且promise1拒绝执行,promise2必须拒绝执行并返回相同的拒因

  3. Promise解决过程

    该过程比较复杂,配合看点实例。

    一个抽象的操作,它接收一个promise和一个值,我们可以表示为[[Resolve]](promise,x),如果x是一个thenable对象,解决程序将试图接受x的状态,否则用x的值来执行promise。

    这种对thenable的处理具有普适性。

    运行[[Resolve]](promise,x)的步骤:

    • promisex指向同一对象,则以TypeError作为拒因拒绝执行
          let promise2 = new Promise(resolve=>resolve(10)).then(()=>promise2)
          =>Uncaught (in promise) TypeError: A promise cannot be resolved with itself.
      
      明显这个性质是为了防止循环引用
  • x是一个promise,那么promise将接受它的状态:

    Pending:promise必须保留状态直到x被完成或者被拒绝

    Fulfilled:用相同的值执行promise

    Rejected:用相同的原因拒绝promise

    let promise1 = new Promise(resolve=>resolve(0))
    console.log(promise1)
    =>Promise {
          <state>: "fulfilled", <value>: 0 }
    let promise2 = new Promise(resolve=>resolve(promise1))
    console.log(promise2)
    =>Promise {
          <state>: "fulfilled", <value>: 0 }
    console.log(promise2 == promise1)
    =>false
    

可以看到then方法返回的是与promise1相同的状态和值,而且返回的promise是新的promise

  • x是一个对象或者一个函数:

    • x.then赋值给then

    • 如果取 x.then 的值时抛出错误 e,则以 e 为拒因拒绝 promise

    • then是函数,将x作为函数的作用域this来调用它。传递两个回调函数作为参数,为resolvePromiserejectPromise

      1. 如果resolvePromisey为参数被调用,执行[[Resolve]](promise,y)

        let promise1 = new Promise(resolve=>resolve({
                 
          then(resolve,reject){
                 resolve(1)}
        }))
        console.log(promise1)
        =>Promise {
                  <state>: "fulfilled", <value>: 1 }
        

        运行了resolve(1)的过程;

      2. 如果rejectPromiser原因被调用,则以拒因r拒绝promise

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值