# Promise

最简实现 Promise,支持异步链式调用(20 行 (opens new window)

# 基础术语

  • promise 是一个包含 then 方法的对象或函数,该方法符合规范指定的行为

  • thenable 是一个包含 then 方法和对象或者函数

  • value 就是任意合法 JS 值

  • exception 就是 throw 语句抛出的值

  • reason 是一个指示 promise 为什么被 rejected 的值

const isFunction = (obj) => typeof obj === 'function'
const isObject = (obj) => !!(obj && typeof obj === 'object')
const isThenable = (obj) => (isFunction(obj) || isObject(obj)) && 'then' in obj
const isPromise = (promise) => promise instanceof Promise

const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'

function Promise(f) {
  this.result = null
  this.state = PENDING
  this.callbacks = []

  let onFulfilled = (value) => transition(this, FULFILLED, value)
  let onRejected = (reason) => transition(this, REJECTED, reason)

  let ignore = false
  let resolve = (value) => {
    if (ignore) return
    ignore = true
    resolvePromise(this, value, onFulfilled, onRejected)
  }
  let reject = (reason) => {
    if (ignore) return
    ignore = true
    onRejected(reason)
  }

  try {
    f(resolve, reject)
  } catch (error) {
    reject(error)
  }
}

Promise.prototype.then = function (onFulfilled, onRejected) {
  return new Promise((resolve, reject) => {
    let callback = { onFulfilled, onRejected, resolve, reject }

    if (this.state === PENDING) {
      this.callbacks.push(callback)
    } else {
      setTimeout(() => handleCallback(callback, this.state, this.result), 0)
    }
  })
}

const handleCallback = (callback, state, result) => {
  let { onFulfilled, onRejected, resolve, reject } = callback
  try {
    if (state === FULFILLED) {
      isFunction(onFulfilled) ? resolve(onFulfilled(result)) : resolve(result)
    } else if (state === REJECTED) {
      isFunction(onRejected) ? resolve(onRejected(result)) : reject(result)
    }
  } catch (error) {
    reject(error)
  }
}

const handleCallbacks = (callbacks, state, result) => {
  while (callbacks.length) handleCallback(callbacks.shift(), state, result)
}

const transition = (promise, state, result) => {
  if (promise.state !== PENDING) return
  promise.state = state
  promise.result = result
  setTimeout(() => handleCallbacks(promise.callbacks, state, result), 0)
}

const resolvePromise = (promise, result, resolve, reject) => {
  if (result === promise) {
    let reason = new TypeError('Can not fufill promise with itself')
    return reject(reason)
  }

  if (isPromise(result)) {
    return result.then(resolve, reject)
  }

  if (isThenable(result)) {
    try {
      let then = result.then
      if (isFunction(then)) {
        return new Promise(then.bind(result)).then(resolve, reject)
      }
    } catch (error) {
      return reject(error)
    }
  }

  resolve(result)
}

module.exports = Promise

# async

  • async 表示函数里有异步操作

  • 返回值是 Promise

  • async 函数的语法规则总体上比较简单,难点是错误处理机制

# await

  • 正常情况下,await 命令后面是一个 Promise 对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值
上次更新: 5/2/2022, 4:04:58 PM