美文网首页
实现一个Promise

实现一个Promise

作者: 一蓑烟雨任平生_cui | 来源:发表于2021-02-06 16:11 被阅读0次

根据PromiseA+规范实现一个Promise,js无法模拟微任务,通过setTimeout代替。

const PENDING = 'PENDING'
const FULFILLED = 'FULFILLED'
const REJECTED = 'REJECTED'

class Promise {
  constructor(executor) {
    this.status = PENDING
    this.result = undefined
    this.callbacks = []

    const resolve = value => {
      if (this.status === PENDING) {
        this.status = FULFILLED
        this.result = value

        setTimeout(() => {
          this.callbacks.forEach(cb => {
            cb.onResolved(value)
          })
        }, 0)
      }
    }

    const reject = reason => {
      if (this.status === PENDING) {
        this.status = REJECTED
        this.result = reason

        setTimeout(() => {
          this.callbacks.forEach(cb => {
            cb.onRejected(reason)
          })
        }, 0)
      }
    }

    try {
      executor(resolve, reject)
    } catch (e) {
      reject(e)
    }
  }

  then(onResolved, onRejected) {
    onResolved = typeof onResolved === 'function' ? onResolved : value => value // 把 value 透传下去
    onRejected =
      typeof onRejected === 'function'
        ? onRejected
        : reason => {
            // 抛出错误 继续透传下去
            throw reason
          }

    return new Promise((resolve, reject) => {
      const handler = callback => {
        try {
          const value = callback(this.result)

          // 如果返回值 value 是一个 Promise 的实例,则新Promise实例的状态由value的状态决定
          if (value instanceof Promise) {
            value.then(
              res => resolve(res),
              err => reject(err)
            )
          } else {
            resolve(value)
          }
        } catch (e) {
          reject(e)
        }
      }

      // FULFILLED 和 FULFILLED 是针对 executor 是同步的情况
      if (this.status === FULFILLED) {
        setTimeout(() => {
          handler(onResolved)
        }, 0)
      } else if (this.status === FULFILLED) {
        setTimeout(() => {
          handler(onRejected)
        }, 0)
      } else {
        // PENDING
        this.callbacks.push({
          onResolved() {
            handler(onResolved)
          },
          onRejected() {
            handler(onRejected)
          }
        })
      }
    })
  }

  catch(onRejected) {
    return this.then(undefined, onRejected)
  }
}

测试用例:

const p1 = new PromiseX((resolve, reject) => {
    // resolve(2)
    // throw new Error('oops')
    reject('oops')
  })

  p1.then()
    .then(res => {
      console.log(res)
    })
    .catch()
    .catch(err => {
      console.log(err)
      return new PromiseX(res => {
        res('ok')
      })
    })
    .then(res => {
      console.log(res)
    })

关于Promise的静态方法比如:Promise.all、Promise.race、Promise.allSettled等可以查看前端面试总结

相关文章

网友评论

      本文标题:实现一个Promise

      本文链接:https://www.haomeiwen.com/subject/jhdotltx.html