简单版本的 es5 版本

var PENDING = 'pending'
var FULLFILLED = 'fullfilled'
var REJECTED = 'rejected'

function Promise (excutor) {
  var that = this

  this.state = PENDING // 默认为 pending 态
  this.value = undefined // value 默认为 undefined
  this.reason = undefined // reason 默认为 undefined

  this.onFullfilledCallbacks = []
  this.onRejectedCallbacks = []

  function resolve (value) {
    if (that.state === PENDING) {
      that.state = FULLFILLED // resolve 后将 状态改为 fullfilled
      that.value = value

      that.onFullfilledCallbacks.forEach(function (fn) {
        fn && fn()
      })
    }
  }

  function reject (reason) {
    if (that.state === PENDING) {
      that.state = REJECTED // reject 后将 状态改为 rejected
      that.value = reason

      that.onRejectedCallbacks.forEach(function (fn) {
        fn && fn()
      })
    }
  }

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

Promise.prototype.then = function (onFulfilled, onRejected) {
  var that = this
  if (this.state === FULLFILLED) {
    onFulfilled(this.value)
  } else if (this.state === REJECTED) {
    onRejected(this.reason)
  } else {
    this.onFullfilledCallbacks.push(function () {
      onFulfilled(that.value)
    })
    this.onRejectedCallbacks.push(function () {
      onFulfilled(that.reason)
    })
  }
}

简单版本的 es6 版本

const PENDING = 'pending'
const FULLFILLED = 'fullfilled'
const REJECTED = 'rejected'

class Promise {
  constructor(excutor) {
    this.state = PENDING

    this.value = undefined
    this.reason = undefined

    this.onFullfilledCallbacks = []
    this.onRejectedCallbacks = []

    const resolve = value => {
      if (this.state !== PENDING) return
      this.state = FULLFILLED
      this.value = value

      this.onFullfilledCallbacks.forEach(callback => {
        callback && callback()
      })
    }

    const reject = reason => {
      if (this.state !== PENDING) return
      this.state = REJECTED
      this.reason = reason

      this.onRejectedCallbacks.forEach(callback => {
        callback && callback()
      })
    }

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

  then (onFullfilled, onRejected) {
    if (this.state === FULLFILLED) {
      onFullfilled(this.value)
    } else if (this.state === REJECTED) {
      onRejected(this.reason)
    } else {
      this.onFullfilledCallbacks.push(() => {
        onFullfilled(this.value)
      })

      this.onRejectedCallbacks.push(() => {
        onRejected(this.reason)
      })
    }
  }
}