const PENDING = 'pending'const FULFILLED = 'fulfilled'const REJECTED = 'rejected'class Promise {  constructor(executor) {    this.state = PENDING    this.value = null    this.reason = null    this.onFulfilledCallbacks = []    this.onRejectedCallbacks = []    const resolve = value => {      setTimeout(() => {        if (this.state === PENDING) {          this.state = FULFILLED          this.value = value          this.onFulfilledCallbacks.forEach(cb => {            cb = cb(this.value)          })        }      });    }    const reject = reason => {      setTimeout(() => {        if (this.state === PENDING) {          this.state = REJECTED          this.reason = reason          this.onRejectedCallbacks.forEach(cb => {            cb = cb(this.reason)          })        }      });    }    try {      executor(resolve, reject)    } catch (e) {      reject(e)    }  }  then(onFulfilled, onRejected) {    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value    onRejected = typeof onRejected === 'function' ? onRejected : reason => {      throw reason    }    let newPromise    if (this.state === FULFILLED) {      return (newPromise = new Promise((resolve, reject) => {        setTimeout(() => {          try {            let x = onFulfilled(this.value)            resolvePromise(newPromise, x, resolve, reject)          } catch (e) {            reject(e)          }        });      }))    }    if (this.state === REJECTED) {      return (newPromise = new Promise((resolve, reject) => {        setTimeout(() => {          try {            let x = onRejected(this.reason)            resolvePromise(newPromise, x, resolve, reject)          } catch (e) {            reject(e)          }        });      }))    }    if (this.state === PENDING) {      return (newPromise = new Promise((resolve, reject) => {        this.onFulfilledCallbacks.push(value => {          try {            let x = onFulfilled(value)            resolvePromise(newPromise, x, resolve, reject)          } catch (e) {            reject(e)          }        })        this.onRejectedCallbacks.push(reason => {          try {            let x = onRejected(reason)            resolvePromise(newPromise, x, resolve, reject)          } catch (e) {            reject(e)          }        })      }))    }  }}function resolvePromise(promise2, x, resolve, reject) {  if (x === promise2) {    reject(new TypeError())  }  if (x instanceof Promise) {    if (x.state === PENDING) {      x.then(y => {        resolvePromise(promise2, y, resolve, reject)      }, reason => {        reject(reason)      })    } else {      x.then(resolve, reject)    }  } else if (x && (typeof x === 'function' || typeof x === 'object')) {    let called = false    try {    let then = x.then      if (typeof then === 'function') {        then.call(x, y => {          if (called) return          called = true          resolvePromise(promise2, y, resolve, reject)        }, r => {          if (called) return          called = true          reject(r)        })      } else {        resolve(x)      }    } catch (e) {      if (called) return      called = true      reject(e)    }  } else {    resolve(x)  }}