有没有实现过PromiseA+ 的大佬,能告诉我的实现哪里存在问题么?

这是我的实现

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

class APromise {
  constructor(fn) {
    this.value = undefined
    this.state = PENDING
    this.callBackQueue = []
    try {
      fn(this.resolve.bind(this), this.reject.bind(this))
    }
    catch (e) {
      this.reject(e)
    }
  }
  executeQueue() {
    const len = this.callBackQueue.length
    for (let i = 0; i < len; i++) {
      const { onFulfilled, onRejected } = this.callBackQueue[i]
      this.then(onFulfilled,
        onRejected)
    }
  }
  resolve(value) {


    if (this.state === PENDING) {
      if (value === this) {
        return this.reject(new TypeError('failed'))
      }
      if (value && (typeof value === 'object' || typeof value === 'function')) {
        let then
        try {
          then = value.then
        } catch (err) {
          return this.reject(err)
        }

        // promise
        if (then === this.then && this instanceof APromise) {
          this.state = FULFILLED
          this.value = value
          return this.executeQueue()
        }

        // thenable
        if (typeof then === 'function') {
          return this.then(then.bind(this))
        }
      }

      this.state = FULFILLED
      this.value = value
      this.executeQueue()
    }
  }
  reject(reason) {
    if (this.state === PENDING) {
      this.state = REJECTED
      this.value = reason
      this.executeQueue()
    }
  }


  then(onFulfilled, onRejected) {
    const promiseThen = new APromise(() => { })
    let that = this
    while (that.value instanceof APromise && that.state !== REJECTED) {
      that = that.value
    }


    if (that.state === PENDING) {
      that.callBackQueue.push({
        onFulfilled,
        onRejected

      })
    }
    if (that.state === FULFILLED) {
      setTimeout(() => {
        if (typeof onFulfilled !== 'function') {
          promiseThen.resolve(that.value)
        }
        else {
          try {
            const ret = onFulfilled(that.value)
            promiseThen.resolve(ret)
          } catch (err) {
            promiseThen.reject(err)
          }
        }
      },0);
    }
    if (that.state === REJECTED) {
      setTimeout(() => {
        if (typeof onRejected !== 'function') {
          promiseThen.reject(that.value)
          return
        }
        else {
          try {
            const ret = onRejected(that.value)
            promiseThen.resolve(ret)
          } catch (err) {
            promiseThen.reject(err)
          }
        }
      },0);
    }
    return promiseThen
  }
}

可以通过测试用例的实现是如下代码https://github.com/mauriciopoppe/implementing-promises-from-scratch,我想参照进行修改是否可以只通过this去修改,但是并没有通过测试用例

// possible states
const PENDING = 'PENDING'
const FULFILLED = 'FULFILLED'
const REJECTED = 'REJECTED'

class APromise {
  constructor (resolver) {
    // initial state
    this.state = PENDING
    // the fulfillment value or rejection reason is mapped internally to `value`
    // initially the promise doesn't have a value

    // .then handler queue
    this.queue = []

    // call the resolver immediately
    doResolve(this, resolver)
  }

  then (onFulfilled, onRejected) {
    // empty resolver
    const promise = new APromise(() => {})
    handle(this, { promise, onFulfilled, onRejected })
    return promise
  }
}

function handle (promise, handler) {
  // take the state of the returned promise
  while (promise.value instanceof APromise && promise.state !== REJECTED) {
    promise = promise.value
  }

  if (promise.state === PENDING) {
    // queue if PENDING
    promise.queue.push(handler)
  } else {
    // execute immediately
    handleResolved(promise, handler)
  }
}

// call either the onFulfilled or onRejected function
function handleResolved (promise, handler) {
  setImmediate(() => {
    const cb = promise.state === FULFILLED ? handler.onFulfilled : handler.onRejected
    if (typeof cb !== 'function') {
      if (promise.state === FULFILLED) {
        fulfill(handler.promise, promise.value)
      } else {
        reject(handler.promise, promise.value)
      }
      return
    }

    try {
      const ret = cb(promise.value)
      fulfill(handler.promise, ret)
    } catch (err) {
      reject(handler.promise, err)
    }
  })
}

// fulfill with `value`
function fulfill (promise, value) {
  if (value === promise) {
    return reject(promise, new TypeError('failed'))
  }
  if (value && (typeof value === 'object' || typeof value === 'function')) {
    let then
    try {
      then = value.then
    } catch (err) {
      return reject(promise, err)
    }

    // promise
    if (then === promise.then && promise instanceof APromise) {
      promise.state = FULFILLED
      promise.value = value
      return finale(promise)
    }

    // thenable
    if (typeof then === 'function') {
      return doResolve(promise, then.bind(value))
    }
  }

  // primitive
  promise.state = FULFILLED
  promise.value = value
  finale(promise)
}

// reject with `reason`
function reject (promise, reason) {
  promise.state = REJECTED
  promise.value = reason
  finale(promise)
}

function finale (promise) {
  var length = promise.queue.length
  for (var i = 0; i < length; i += 1) {
    handle(promise, promise.queue[i])
  }
}

// creates the fulfill/reject functions that are arguments of the resolver
function doResolve (promise, resolver) {
  let called = false

  function wrapFulfill (value) {
    if (called) { return }
    called = true
    fulfill(promise, value)
  }

  function wrapReject (reason) {
    if (called) { return }
    called = true
    reject(promise, reason)
  }

  try {
    resolver(wrapFulfill, wrapReject)
  } catch (err) {
    wrapReject(err)
  }
}
阅读 394
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题