手撕Promise-相关方法实现

 <script>

      function runAsyncTask(callback) {

        // queueMicroTask() ->  MutationObserver  -> setTimeout()

        if (typeof queueMicrotask === 'function') {

          queueMicrotask(callback)

        } else if (typeof MutationObserver === 'function') {

          const mutationObserver = new MutationObserver(callback)

          const oDiv = document.createElement('div')

          mutationObserver.observe(oDiv, { childList: true })

          oDiv.innerText = 'longge666'

        } else {

          setTimeout(callback, 0)

        }

      }

      function resolvePromise(p2, x, resolve, reject) {

        // 循环引用

        if (x === p2) {

          throw new TypeError('Chaining cycle detected for promise #<Promise>')

        }

        if (x instanceof Promise) {

          // 说明返回值是一个promise的实例

          x.then(

            (data) => {

              resolve(data)

            },

            (err) => {

              reject(err)

            }

          )

        } else {

          // 普通值的时候

          resolve(x)

        }

      }

      // Promise构造函数

      // Promise状态 status pending  fulfilled rejected

      const PENDING = 'pending'

      const FULFILLED = 'fulfilled'

      const REJECTED = 'rejected'

      class Promise {

        //  实例属性

        status = PENDING

        result = undefined

        //  私有属性 this.#handlers = []

        #handles = []

        constructor(executor) {

          // console.log(executor)

          // console.log('构造函数执行了')

          const resolve = (result) => {

            if (this.status === PENDING) {

              this.status = FULFILLED

              this.result = result

              // 把之前存的函数依次取出来调用

              this.#handles.forEach(({ onFulfilled }) => {

                onFulfilled()

              })

            }

          }

          const reject = (result) => {

            if (this.status === PENDING) {

              this.status = REJECTED

              this.result = result

              // 把之前存的函数依次取出来调用

              this.#handles.forEach(({ onRejected }) => {

                onRejected()

              })

            }

          }

          executor(resolve, reject)

        }

        then(onFulfilled, onRejected) {

          onFulfilled =

            typeof onFulfilled === 'function' ? onFulfilled : (x) => x

          onRejected =

            typeof onRejected === 'function'

              ? onRejected

              : (x) => {

                  throw x

                }

          const p2 = new Promise((resolve, reject) => {

            // 判断状态

            if (this.status === FULFILLED) {

              runAsyncTask(() => {

                try {

                  const x = onFulfilled(this.result)

                  resolvePromise(p2, x, resolve, reject)

                } catch (err) {

                  reject(err)

                }

              })

            } else if (this.status === REJECTED) {

              runAsyncTask(() => {

                try {

                  const x = onRejected(this.result)

                  resolvePromise(p2, x, resolve, reject)

                } catch (err) {

                  reject(err)

                }

              })

            } else {

              // 调用then的时候,状态是默认状态,把传入的两个函数存储起来

              // [{onFulfilled, onRejected},{OnFulfilled, onRejected}]

              this.#handles.push({

                onFulfilled: () => {

                  runAsyncTask(() => {

                    try {

                      const x = onFulfilled(this.result)

                      resolvePromise(p2, x, resolve, reject)

                    } catch (err) {

                      reject(err)

                    }

                  })

                },

                onRejected: () => {

                  runAsyncTask(() => {

                    try {

                      const x = onRejected(this.result)

                      resolvePromise(p2, x, resolve, reject)

                    } catch (err) {

                      reject(err)

                    }

                  })

                },

              })

            }

          })

          return p2

        }

        catch(onRejected) {

          return this.then(undefined, onRejected)

        }

        finally(onFinally) {

          return this.then(onFinally, onFinally)

        }

      }

      /**/

      const p = new Promise((resolve, reject) => {

        //resolve(1)

        reject('error')

      })

      // then可以调用多次

      const p2 = p

        .then((data) => {

          console.log(data) // 1

          return 100

        })

        .catch((err) => {

          console.log(err)

        })

        .finally((x) => {

          console.log(x)

          console.log('肯定会执行')

        })

      //  catch  all ...

      //  race any allSettled

      // bind

      // promise a+规范

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值