当前位置:
首页
文章
移动端
详情

基于Class实现简易的promise

用class实现了一个简易的promise

  1. 包含三种状态:pending、fulfilled、rejected,同时做了状态凝固
  2. 实现了resolved、reject的异步执行,利用了一个数组来保存当then时state仍然为pending的问题
  3. 实现了链式调用,在then中返回了一个promise,且对onFufilled及onRejected做了类型判断
    4.resolvePromise函数:判断对then中返回值的不同类型做了相应处理,同时针对then中return的promise2与回调函数中返回的结果x做了判断,防止循环引用报错
    5.最后,由于在获取步骤四中回调函数的返回结果x时,return的promise2并没有值,因此对整个执行过程用异步来实现,以获取promise2的值
class Promise {
          constructor(executor) {
            this.state = 'pending'
            this.value = undefined
            this.reason = undefined

            this.onResolvedCallbacks = []
            this.onRejectedCallbacks = []

            let resolve = (value) => {
              if (this.state === 'pending') {
                this.state = 'fulfilled'
                this.value = value
                this.onResolvedCallbacks.forEach(fn => fn())
              }
            }

            let reject = (reason) => {
              if (this.state === 'pending') {
                this.state = 'rejected'
                this.reason = reason
                this.onRejectedCallbacks.forEach(fn => fn())
              }
            }

            try {
              executor(resolve, reject)
            } catch (err) {
              reject(err)
            }
          }
          // 实现链式 返回promise对象
          then(onFulfilled, onRejected) {
            onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value
            onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err }

            //返回promise2 完成链式调用
            let promise2 = new Promise((resolve, reject) => {
                if (this.state === 'fulfilled') {
                  setTimeout(() => {
                    try {
                      let x = onFulfilled(this.value)
                      resolvePromise(promise2, x, resolve, reject)
                    } catch (e) {
                      reject(e)
                    }
                  }, 0)
                }
                
                if (this.state === 'rejected') {
                  setTimeout(() => {
                    try {
                      let x = onRejected(this.reason)
                      resolvePromise(promise2, x, resolve, reject)
                    } catch (e) {
                      reject(e)
                    }
                  }, 0)
                }
                if (this.state === 'pending') {
                  this.onResolvedCallbacks.push(() => {
                    //此处写回调函数的目的是为了保留value参数
                    setTimeout(() => {
                      try {
                        let x = onFulfilled(this.value)
                        resolvePromise(promise2, x, resolve, reject)
                      } catch (e) {
                        reject(e)
                      }
                    }, 0)

                  })
                  this.onRejectedCallbacks.push(() => {
                    setTimeout(() => {
                      try {
                        let x = onRejected(this.reason)
                        resolvePromise(promise2, x, resolve, reject)
                      } catch (e) {
                        reject(e)
                      }
                    }, 0)
                  })
                }
            })
            return promise2
          }

          catch(fn){
                return this.then(null,fn)
            }
        }

        function resolvePromise(promise2, x, resolve, reject) {
          if (x === promise2) {
            return reject(new TypeError('Chaining cycle detected for promise'))
          }

          if (x instanceof Promise) {
            //promise值
            x.then((value) => {
                resolve(value)
            }, err => {
                reject(err)
            })
          } else {
            //普通值
            resolve(x)
          }
        }

免责申明:本站发布的内容(图片、视频和文字)以转载和分享为主,文章观点不代表本站立场,如涉及侵权请联系站长邮箱:xbc-online@qq.com进行反馈,一经查实,将立刻删除涉嫌侵权内容。