Promises/A+实现,一条规范对应一段代码

2,316 阅读15分钟

1. Terminology

  1. “promise” is an object or function with a then method whose behavior conforms to this specification.
  2. “thenable” is an object or function that defines a then method.
  3. “value” is any legal JavaScript value (including undefined, a thenable, or a promise).
  4. “exception” is a value that is thrown using the throw statement.
  5. “reason” is a value that indicates why a promise was rejected.

2. Requirements

2.1 Promise States

A promise must be in one of three states: pending, fulfilled, or rejected.

为了防止后续字符串写错,我们写成三个常量来表示这三种状态

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

2.1.1 When pending, a promise:

  1. may transition to either the fulfilled or rejected state.

2.1.2 When fulfilled, a promise:

  1. must not transition to any other state.

  2. must have a value, which must not change.

2.1.3 When rejected, a promise:

  1. must not transition to any other state.

  2. must have a reason, which must not change.

Here, “must not change” means immutable identity (i.e. ===), but does not imply deep immutability.

class Promise {
  constructor(executor) {
    this.status = PENDING

    let resolve = data => {
      if (this.status === PENDING){
        this.status = FULFILLED
        this.value = data
      }
    }
    let reject = reason => {
      if (this.status === PENDING){
        this.status = REJECTED
        this.value = reason
      }
    }

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

2.2 The then Method

A promise must provide a then method to access its current or eventual value or reason.

A promise’s then method accepts two arguments:

promise.then(onFulfilled, onRejected)

所以 我们现在 写

class Promise {
  constructor(executor) {
    // ...
  }
  then(onFulfilled, onRejected) {

  }
}

2.2.1 Both onFulfilled and onRejected are optional arguments

  1. If onFulfilled is not a function, it must be ignored.

  2. If onRejected is not a function, it must be ignored.

class Promise {
  constructor(executor) {
    // ...
  }
  then(onFulfilled, onRejected) {
   onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
   onRejected = typeof onRejected == 'function' ? onRejected : reason => { throw reason }
   // 如果代码执行到这,onFulfilled和onRejected必定为函数
  }
}

如果不是函数,我们就忽略用户的值,直接使用我们内部自定义的函数。

上面的函数实现缘由会在后面再次说明

2.2.2 If onFulfilled is a function

  1. it must be called after promise is fulfilled, with promise’s value as its first argument.

  2. it must not be called before promise is fulfilled.

  3. it must not be called more than once.

如果在给 Promise通过then绑定回调函数时,Promise的状态已经是FULFILLED时,我们就直接执行传进来的回调函数

then(onFulfilled,onRejected){
  if (this.status === FULFILLED) {
    onFulfilled(this.value)
  }
}

2.2.3 If onRejected is function

  1. it must be called after promise is rejected, with promise’s reason as its first argument.

  2. it must not be called before promise is rejected.

  3. it must not be called more than once.

then(onFulfilled,onRejected){
  if (this.status === REJECTED) {
    onRejected(this.value)
  }
}

2.2.4 onFulfilled or onRejected must not be called until the execution context stack contains only platform code. [3.1].

3.1 Here “platform code” means engine, environment, and promise implementation code. In practice, this requirement ensures thatconFulfilled and onRejected execute asynchronously, after the event loop turn in which then is called, and with a fresh stack. This can be implemented with either a “macro-task” mechanism such as setTimeout or setImmediate, or with a “micro-task” mechanism such as MutationObserver or process.nextTick. Since the promise implementation is considered platform code, it may itself contain a task-scheduling queue or “trampoline” in which the handlers are called.

简单来说,就是onFulfilledonRejected这些回调函数必须异步调用,这里我们使用最简单的方式,即setTimeout

只要把上面执行onFulfilledonRejected的代码,放在setTimeout里面,这样就不会立即执行了。回调函数就可以异步执行了.

if (this.status === FULFILLED) {
  let timer = setTimeout(() => {
    clearTimeout(timer)
    onFulfilled(this.value)
  })
  }
if (this.status === REJECTED) {
  let timer = setTimeout(() => {
    clearTimeout(timer)
    onRejected(this.value)
  })
  }

2.2.5 onFulfilled and onRejected must be called as functions (i.e. with no this value). [3.2]

3.2 That is, in strict mode this will be undefined inside of them; in sloppy mode, it will be the global object.

2.2.6 then may be called multiple times on the same promise.

上面我们处理的情况是,函数已经成功或者失败时执行相应的回调函数

那在添加回调时,状态还是pending,那我们就不应该执行回调函数了

另外我们对同一个Promise对象可以then多次,即在该对象上挂载多个成功或失败回调函数

当promise成功或失败时再依次执行。

那没执行前,我们就需要缓存起来

因此我们设置两个数组来存放回调函数

class Promise {
  constructor(executor) {
    // 定义存放 成功后 执行的回调数组
    this.onResolvedCallbacks = []
    // 定义存放 失败后 执行的回调数组
    this.onRejectedCallbacks = []
  }
}

在执行then时,如果此时的Promise状态还是pending,就把方法push到上述的数组里。

Promise{
  // ...
  then(){
    // ...
    if (this.state === PENDING) {
      preomise2 = new Promise((resolve, reject) => {
        this.onResolvedCallbacks.push(onFulfilled)
        this.onRejectedCallbacks.push(onRejected)
      })
    }
    // ...
  }
}
  1. If/when promise is fulfilled, all respective onFulfilled callbacks must execute in the order of their originating calls to then.

  2. If/when promise is rejected, all respective onRejected callbacks must execute in the order of their originating calls to then.

那当我们更改状态时,即执行resolvereject时,就开始遍历执行回调数组里的函数

class Promise {
  constructor(executor) {
    // ...
    this.onResolvedCallbacks = []
    this.onRejectedCallbacks = []

    let resolve = data => {
      // ..
      this.onResolvedCallbacks.forEach(cb => cb(this.value))
      // ..
    }

    let reject = reason => {
      // ..
      this.onRejectedCallbacks.forEach(cb => cb(this.value))
      // ..
    }
    // ...

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

但是我们再回顾

2.2.4 onFulfilled or onRejected must not be called until the execution context stack contains only platform code.

我们的回调函数需要异步执行,而上面的代码却是会同步执行的,所以同理我们需要在这里使用setTimeout来使代码异步执行

上面代码中遍历取得的cb就是我们的onFulfilledonRejected

class Promise {
  constructor(executor) {
    this.status = PENDING
    this.value = undefined
    this.onResolvedCallbacks = []
    this.onRejectedCallbacks = []

    let resolve = data => {
      let timer = setTimeout(() => {
        clearTimeout(timer)
        if (this.status === PENDING) {
          this.status = FULFILLED
          this.value = data
          // 遍历执行成功回调
          this.onResolvedCallbacks.forEach(cb => cb(this.value))
        }
      })
      }
    
    let reject = reason => {
      let timer = setTimeout(() => {
        clearTimeout(timer)
        if (this.status === PENDING) {
          this.status = REJECTED
          this.value = reason
          // 遍历执行失败回调
          this.onRejectedCallbacks.forEach(cb => cb(this.value))
        }
      })
      }

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

2.2.7 then must return a promise [3.3].

3.3 Implementations may allow promise2 === promise1, provided the implementation meets all requirements. Each implementation should document whether it can produce promise2 === promise1and under what conditions.

 promise2 = promise1.then(onFulfilled, onRejected);

那么我们前面的操作应该都包裹在promise2 = new Promise(resolve, reject) =>{ }里面,然后把promise2返回

那我们的回调函数返回的数据就可以通过Promise2.resolve(value)Promise2.reject(reason)的参数进行传递

我们就可以通过以下形式获取到数据

let promise2 = new Promise((resolve, reject) => {
  resolve('data')
  reject('reason')
})
promise2.then(
  data => console.log(data),
  reason => console.log(reason)
)

所以现在我们把代码都包裹在promise里面

then(onFulfilled, onRejected) {
  // ...
  let promise2

  if (this.status === FULFILLED) {
    promise2 = new Promise((resolve, reject) => {
      // ...
    })
  }
  if (this.status === REJECTED) {
    promise2 = new Promise((resolve, reject) => {
      // ...
    })
  }
  if (this.status === PENDING) {
    promise2 = new Promise((resolve, reject) => {
      // ...
    })
  }

  return promise2
}

1. If either onFulfilled or onRejected returns a value x, run the Promise Resolution Procedure [[Resolve]](promise2, x).

这里我们需要再定义一个[[Resolve]](promise2, x)方法,我们就取名为resolvePromise,

function resolvePromise(promise2, x, resolve, reject) { } 

用来解析promise,具体如何解析在后面会2.3说明

该方法是用来解析回调函数返回的值的,我们希望通过resolvereject传递过去的值是一个普通值,即非thenable的,具体细节在后面讲.

2. If either onFulfilled or onRejected throws an exception e, promise2 must be rejected with e as the reason.

如果是错误的话,一定是一个普通值,我们直接preject传递出去就可以了

if (this.status === FULFILLED) {
  promise2 = new Promise((resolve, reject) => {
    let timer = setTimeout(() => {
      clearTimeout(timer)
      try {
        let x = onFulfilled(this.value)
        resolvePromise(promise2, x, resolve, reject)
      } catch (e) {
        reject(e)
      }
    })
    })
}

if (this.status === REJECTED) {
  promise2 = new Promise((resolve, reject) => {
    let timer = setTimeout(() => {
      clearTimeout(timer)
      try {
        let x = onRejected(this.value)
        resolvePromise(promise2, x, resolve, reject)
      } catch (e) {
        reject(e)
      }
    })
    })
}

if (this.status === PENDING) {
  promise2 = new Promise((resolve, reject) => {
    this.onResolvedCallbacks.push(value => {
      try {
        let x = onFulfilled(value)
        resolvePromise(promise2, x, resolve, reject)
      } catch (e) {
        reject(e)
      }
    })
    this.onRejectedCallbacks.push(reason => {
      try {
        let x = onRejected(reason)
        resolvePromise(promise2, x, resolve, reject)
      } catch (e) {
        reject(e)
      }
    })
  })
}

3. If onFulfilled is not a function and promise1 is fulfilled, promise2 must be fulfilled with the same value as promise1.

4. If onRejected is not a function and promise1 is rejected, promise2 must be rejected with the same reason as promise1.

这就是前面讲到的如果用户传递进来的onFulFilledonRejected不是函数的话,我们就忽略掉,定义为内部的函数

onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value
onRejected = typeof onRejected == 'function' ? onRejected : reason => { throw reason }

简单来说就是把值往后抛,让下个then可以获取得到这个then的数据。

Promise
  .resolve(4)
  .then()
  .then(val => console.log(val))

综上,我们就把 then方法的全部代码实现了

then(onFulfilled, onRejected) {
  onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
  onRejected = typeof onRejected == 'function' ? onRejected : reason => { throw reason };
  let promise2

  if (this.status === FULFILLED) {
    promise2 = new Promise((resolve, reject) => {
      let timer = setTimeout(() => {
        clearTimeout(timer)
        try {
          let x = onFulfilled(this.value)
          resolvePromise(promise2, x, resolve, reject)
        } catch (e) {
          reject(e)
        }
      })
      })
  }
  if (this.status === REJECTED) {
    promise2 = new Promise((resolve, reject) => {
      let timer = setTimeout(() => {
        clearTimeout(timer)
        try {
          let x = onRejected(this.value)
          resolvePromise(promise2, x, resolve, reject)
        } catch (e) {
          reject(e)
        }
      })
      })
  }
  if (this.status === PENDING) {
    promise2 = new Promise((resolve, reject) => {
      this.onResolvedCallbacks.push(value => {
        try {
          let x = onFulfilled(value)
          resolvePromise(promise2, x, resolve, reject)
        } catch (e) {
          reject(e)
        }
      })
      this.onRejectedCallbacks.push(reason => {
        try {
          let x = onRejected(reason)
          resolvePromise(promise2, x, resolve, reject)
        } catch (e) {
          reject(e)
        }
      })
    })
  }

  return promise2
};

接下来我们来看我们先前定义的resolvePromise

2.3 The Promise Resolution Procedure

现在来看解析promise过程了,就是我们刚刚写的

function resolvePromise(promise2, x, resolve, reject) { }

我们再来明确下promise2和x是指向什么

我们在执行then方法会返回一个新的Promise,即promise2

let p1 = new Promise((resolve, reject) => {resolve('数据')})
let promise2 = p1.then(data => {
  x = data + '经过了p1处理'
  return x
})
console.log(promise2); // Promise { <pending> }
promise2.then(data => console.log(data)) // 数据经过了p1处理
  • promise2指的是,p1.then方法返回的对象
  • x指的是p1.thenp1添加的回调函数执行后返回的值

如果x是普通值,就像上面一样我们直接打印出来了

但是x可能是一个thenable对象

let p1 = new Promise((resolve, reject) => { resolve('数据') })
let promise2 = p1.then(() => {
  let x = new Promise((resolve, reject) => { resolve('x是一个promise') })
  return x
}
                      )
promise2.then(data => {
  console.log(data); //x是一个promise
})

但是我们在执行代码第8行输出data时,输出的却是一个普通值,而不是输出直接输出new Promise((resolve, reject) => { resolve('x是一个promise') })

因为如果返回的值是一个thenable对象,我们就会解析成普通值后再返回

// ...
let x = onFulfilled(this.value)
resolvePromise(promise2, x, resolve, reject) //这里就是对回调函数返回值进行解析
// ...

resolvePromise的目的就是如果x是普通值就直接执行promise2.resolve(x),如果不是普通值就进行解析后,直到把x转换为普通值后再执行promise2.resolve(x),当然只要是错误了直接就执行promise2.reject(x)

那如何解析成普通值就是我们接下来要做的

2.3.1 If promise and x refer to the same object, reject promise with a TypeError as the reason.

function resolvePromise(promise2, x, resolve, reject) {
  if (promise2 === x) {
    return reject(new TypeError('循环引用'));
  }
}

循环引用的情况

let p1 = new Promise((resolve, reject) => {
  resolve()
})
let p2 = p1.then(() => p2)
p2.then(null, reason => {
  console.log(reason); // TypeError: 循环引用
})

p1.then(() => p2)里的() => p2就是我们的成功回调函数,返回p2,这里返回的数据,即上述的x

2.3.2 If x is a promise, adopt its state [3.4]:

[3.3] Generally, it will only be known that x is a true promise if it comes from the current implementation. This clause allows the use of implementation-specific means to adopt the state of known-conformant promises.

  1. If x is pending, promise must remain pending until x is fulfilled or rejected.

    如果x是一个Promise,我们必须等它完成(失败或成功)后得到一个普通值时,才能继续执行。

    那我们把要执行的任务放在x.then()的成功回调和失败回调里面即可,这就表示x完成后就会调用我们的代码。

    • 如果成功时,执行promise2resolve(value)
  • 如果失败时,执行promise2reject(reason)

但是对于成功的情况,我们还需要再考虑下,x.then成功回调函数的参数,我们称为y,那y也可能是一个thenable对象

所以我们应该把上面的改成

  • 如果成功时,执行resolvePromise(promise2, y, resolve, reject)

这样最终执行promise2.resolve(value)中的这个value就一定是一个非thenable对象

resolvePromise函数中,如果x不是 thenable对象就会执行resolve(x)从而结束递归.

这条属于后面的规范,后面会讲到

if (x instanceof Promise) {
  if (x.status == PENDING) {
    x.then(
      y => resolvePromise(promise2, y, resolve, reject),
      r => reject(r)
      // reject //这么写也是可以的,只是为了和上面对称,把reject用一个函数又包装起来了
    )
  }
} 

在上面的代码中yx(x为promise对象)成功返回的值,如果y是一个普通值

  1. If/when x is fulfilled, fulfill promise with the same value.

  2. If/when x is rejected, reject promise with the same reason.

if (x instanceof Promise) {
  if (x.status == PENDING) {
    x.then(
      y => { resolvePromise(promise2, y, resolve, reject) },
      r => reject(r)
    )
  } else x.then(resolve, reject);
}

如果x此时 已经是完成的,那我们直接把resolvereject传递进去, 就会立即执行了,因为是完成的,所以他的值一定是普通值

2.3.3 Otherwise, if x is an object or function,

以下的处理都是为了兼容性处理,当我们的promise和别的promise进行交互的时候,他们的promise可能是自己写的也可能是引用第三方库的,所以无法直接使用x instanceof Promise来判断,我们就称他们为thanable

thenable,表示一个对象或者函数拥有then方法,我们用段代码表示

if (p !== null &&
    (typeof p === 'object' ||typeof p === 'function') &&
    typeof p.then === 'function') {
  // p 为 thenable
} else {
  // p 不为 thenable
}

当然,原生的promise一定是一个thenable

那说明,如果我们这里实现了thenable的逻辑,上面的判断x是一个promise的处理,完全可以删除掉。

下面我们开始处理thenable

if (x instanceof Promise) {
  // ...
} else if (x != null && ((typeof x == 'object') || (typeof x == 'function'))) {
  // ...
}
  1. Let then be x.then. [3.5]

else if (x != null && ((typeof x == 'object') || (typeof x == 'function'))) {
  let then = x.then;
}

3.5 This procedure of first storing a reference to x.then, then testing that reference, and then calling that reference, avoids multiple accesses to the x.then property. Such precautions are important for ensuring consistency in the face of an accessor property, whose value could change between retrievals.

这里的意思是,我们先不判断then是不是方法,后面再判断。

  1. If retrieving the property x.then results in a thrown exception e, reject promise with e as the reason.

    在获取x.then是,可能报错,所以我们需要try/catch起来,如果报错了就执行reject

    当然,正常情况下是不会报错的,下面代码演示了报错的情况

let obj = {}
Object.defineProperty(obj, 'then', {
  get() {
    throw Error('取then出异常了')
    return function (onFulfilled, onReject) {
    }
  },
  set() { }
})
console.log(obj.then());

所以上面获取x.then的地方,应该用try/catch包住

else if (x != null && ((typeof x == 'object') || (typeof x == 'function'))) {
  try{
    let then = x.then;
  }catch(e){
    reject(e)
  }
}
  1. If then is a function, call it with x as this, first argument resolvePromise, and second argument rejectPromise, where:

    1. If/when resolvePromise is called with a value y, run [[Resolve]](promise, y).
    2. If/when rejectPromise is called with a reason r, reject promise with r.
    else 	if (x != null && ((typeof x == 'object') || (typeof x == 'function'))) {
      try {
        let then = x.then;
        if (typeof then === 'function') {
          then.call(
            x,
            y => resolvePromise(promise2, y, resolve, reject),
            r => reject(r)
          )
        }
      } catch (e) {
        reject(e)
      }
    }
    

    x作为thenthis实际上就是执行以下代码

    x.then(
      y => { resolvePromise(promise2, y, resolve, reject) },
      r => reject(r)
    )
    

    我们会发现代码和上面xpromise时的处理一模一样的

    1. If both resolvePromise and rejectPromise are called, or multiple calls to the same argument are made, the first call takes precedence, and any further calls are ignored.

    resolvePromiserejectPromise只能执行其中的一个,因为要符合状态要么是

    • pending → fulfilled

    • pending → rejected

    • pending只能改变一次

    如果resolvePromiserejectPromise同时执行了,pending就改变了两次

    所以,我们使用一个变量called来限制

    if (x instanceof Promise) {
      // ...
    } else if (x != null && ((typeof x == 'object') || (typeof x == 'function'))) {
      //promise2是否已经resolve 或reject了
      let called = false;
      try {
        let then = x.then;
        if (typeof then == 'function') {
          then.call(
            x,
            y => {
              //防止promise会同时执行成功和失败的回调
              //如果promise2已经成功或失败了,则不会再处理了
              if (called) return;
              called = true;
              resolvePromise(promise2, y, resolve, reject);
            },
            r => {
              //防止promise会同时执行成功和失败的回调
              //如果promise2已经成功或失败了,则不会再处理了
              if (called) return;
              called = true;
              reject(r);
            });
        } catch (e) {
          // ...
        }
      }
    
    1. If calling then throws an exception e,
      1. If resolvePromise or rejectPromise have been called, ignore it.
      2. Otherwise, reject promise with e as the reason.

      同样的道理,我们报错这里也需要进行限制

    if (x instanceof Promise) {
      // ...
    } else if (x != null && ((typeof x == 'object') || (typeof x == 'function'))) {
      //promise2是否已经resolve 或reject了
      let called = false;
      try {
        // ...
      } catch (e) {
        //防止promise会同时执行成功和失败的回调
        //如果promise2已经成功或失败了,则不会再处理了
        if (called) return;
        called = true;
        reject(e);
      }
    }
    
  2. If then is not a function, fulfill promise with x.

如果x是一个对象或者函数,但是x.then不是一个方法,那x也不符合thenable的定义,即x是一个普通值

那对于是普通值,我们当然是直接resolve就可以了

function resolvePromise(promise2, x, resolve, reject) {
  // ...
  if (x instanceof Promise) {
    // ...
  } else if (x != null && ((typeof x == 'object' || typeof x == 'function'))) {
    try {
      // ...
      if (typeof then == 'function') {
        // ...
      } else {
        // then 不是一个函数
        resolve(x);
      }
    } catch (e) {
      // ...
    }
  } else{
      // ...
  }
}

我们可以举个例子

let p1 = Promise.resolve(1)
let p2 = p1.then(() => {
  return {
    name: 'wcdaren',
    then: '不是方法'
  }
})
p2.then(
  data => console.log(`data:${data}`),
  error => console.log(`error:${error}`)
)

上面返回的是一个对象,但是then属性却不是函数

2.3.4 If x is not an object or function, fulfill promise with x.

if (x instanceof Promise) {
  // ...
} else if (x != null && ((typeof x == 'object') || (typeof x == 'function'))) {
  // ...
} else {
  // x 是一个普通值
  resolve(x);
}

这里的x就是最简单,非promise非thenable,我们直接resovle处理就可以了。

他的情况就是

let p1 = Promise.resolve(1)
let p2 = p1.then(() => 1) // x 就是这里的 1 走的是p2的resovle
p2.then(
  data => console.log('p2.resvole', data), //执行p2的resolve
  e => console.log('p2.reject', e)
)
// p2.resvole 1

测试

我们在后面的添加以下代码

Promise.deferred = Promise.defer = function () {
  var defer = {};
  defer.promise = new Promise(function (resolve, reject) {
    defer.resolve = resolve;
    defer.reject = reject;
  })
  return defer;
}
try {
  module.exports = Promise
} catch (e) {
}

使用脚本测试

npm i -g promises-aplus-tests
promises-aplus-tests Promise.js

附带全代码

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

function resolvePromise(promise2, x, resolve, reject) {
	if (promise2 === x) {
		return reject(new TypeError('循环引用'));
	}
	let then
	let called = false
	if (x instanceof Promise) {
		if (x.status == PENDING) {
			x.then(
				y => resolvePromise(promise2, y, resolve, reject),
				r => reject(r)
			)
		} else x.then(resolve, reject);
	} else if (x != null && ((typeof x == 'object' || typeof x == 'function'))) {
		try {
			then = x.then;
			if (typeof then == 'function') {
				then.call(
					x,
					y => {
						//防止promise会同时执行成功和失败的回调
						//如果promise2已经成功或失败了,则不会再处理了
						if (called) return;
						called = true;
						resolvePromise(promise2, y, resolve, reject);
					},
					r => {
						//防止promise会同时执行成功和失败的回调
						//如果promise2已经成功或失败了,则不会再处理了
						if (called) return;
						called = true;
						reject(r);
					});
			} else {
				resolve(x);
			}
		} catch (e) {
			if (called) return;
			called = true;
			reject(e);
		}
	} else {
		resolve(x);
	}
}

class Promise {
	constructor(executor) {
		// 设置状态
		this.status = PENDING
		this.value = undefined
		// 定义存放 成功后 执行的回调数组
		this.onResolvedCallbacks = []
		// 定义存放 失败后 执行的回调数组
		this.onRejectedCallbacks = []

		let resolve = data => {
			let timer = setTimeout(() => {
				clearTimeout(timer)
				if (this.status === PENDING) {
					this.status = FULFILLED
					this.value = data
					this.onResolvedCallbacks.forEach(cb => cb(this.value))
				}

			})
		}
		let reject = reason => {
			let timer = setTimeout(() => {
				clearTimeout(timer)
				if (this.status === PENDING) {
					this.status = REJECTED
					this.value = reason
					this.onRejectedCallbacks.forEach(cb => cb(this.value))
				}
			})
		}

		try {
			executor(resolve, reject)
		} catch (error) {
			reject(error)
		}
	}
	then(onFulfilled, onRejected) {
		onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
		onRejected = typeof onRejected == 'function' ? onRejected : reason => { throw reason };
		let promise2

		if (this.status === FULFILLED) {
			promise2 = new Promise((resolve, reject) => {
				let timer = setTimeout(() => {
					clearTimeout(timer)
					try {
						let x = onFulfilled(this.value)
						resolvePromise(promise2, x, resolve, reject)
					} catch (e) {
						reject(e)
					}
				})
			})
		}
		if (this.status === REJECTED) {
			promise2 = new Promise((resolve, reject) => {
				let timer = setTimeout(() => {
					clearTimeout(timer)
					try {
						let x = onRejected(this.value)
						resolvePromise(promise2, x, resolve, reject)
					} catch (e) {
						reject(e)
					}
				})
			})
		}
		if (this.status === PENDING) {
			promise2 = new Promise((resolve, reject) => {
				this.onResolvedCallbacks.push(value => {
					try {
						let x = onFulfilled(value)
						resolvePromise(promise2, x, resolve, reject)
					} catch (e) {
						reject(e)
					}
				})
				this.onRejectedCallbacks.push(reason => {
					try {
						let x = onRejected(reason)
						resolvePromise(promise2, x, resolve, reject)
					} catch (e) {
						reject(e)
					}
				})
			})
		}

		return promise2
	}
}

// 测试
Promise.deferred = Promise.defer = function () {
	var defer = {};
	defer.promise = new Promise(function (resolve, reject) {
		defer.resolve = resolve;
		defer.reject = reject;
	})
	return defer;
}
try {
	module.exports = Promise
} catch (e) {
}