1. Terminology
- “promise” is an object or function with a
then
method whose behavior conforms to this specification. - “thenable” is an object or function that defines a
then
method. - “value” is any legal JavaScript value (including
undefined
, a thenable, or a promise). - “exception” is a value that is thrown using the
throw
statement. - “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:
-
may transition to either the fulfilled or rejected state.
2.1.2 When fulfilled, a promise:
-
must not transition to any other state.
-
must have a value, which must not change.
2.1.3 When rejected, a promise:
-
must not transition to any other state.
-
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
-
If
onFulfilled
is not a function, it must be ignored. -
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
-
it must be called after
promise
is fulfilled, withpromise
’s value as its first argument. -
it must not be called before
promise
is fulfilled. -
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
-
it must be called after
promise
is rejected, withpromise
’s reason as its first argument. -
it must not be called before
promise
is rejected. -
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 thatc
onFulfilled
andonRejected
execute asynchronously, after the event loop turn in whichthen
is called, and with a fresh stack. This can be implemented with either a “macro-task” mechanism such assetTimeout
orsetImmediate
, or with a “micro-task” mechanism such asMutationObserver
orprocess.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.
简单来说,就是onFulfilled
和onRejected
这些回调函数必须异步调用,这里我们使用最简单的方式,即setTimeout
。
只要把上面执行onFulfilled
和onRejected
的代码,放在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 beundefined
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)
})
}
// ...
}
}
-
If/when promise is fulfilled, all respective onFulfilled callbacks must execute in the order of their originating calls to then.
-
If/when promise is rejected, all respective onRejected callbacks must execute in the order of their originating calls to then.
那当我们更改状态时,即执行resolve
和reject
时,就开始遍历执行回调数组里的函数
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
oronRejected
must not be called until the execution context stack contains only platform code.
我们的回调函数需要异步执行,而上面的代码却是会同步执行的,所以同理我们需要在这里使用setTimeout
来使代码异步执行
上面代码中遍历取得的cb
就是我们的onFulfilled
和onRejected
。
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 producepromise2 === promise1
and 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说明
该方法是用来解析回调函数返回的值的,我们希望通过resolve
和reject
传递过去的值是一个普通值,即非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
.
这就是前面讲到的如果用户传递进来的onFulFilled
和onRejected
不是函数的话,我们就忽略掉,定义为内部的函数
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.then
往p1
添加的回调函数执行后返回的值
如果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.
-
If
x
is pending,promise
must remain pending untilx
is fulfilled or rejected.如果
x
是一个Promise
,我们必须等它完成(失败或成功)后得到一个普通值时,才能继续执行。那我们把要执行的任务放在
x.then()
的成功回调和失败回调里面即可,这就表示x
完成后就会调用我们的代码。- 如果成功时,执行
promise2
的resolve(value)
- 如果成功时,执行
- 如果失败时,执行
promise2
的reject(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用一个函数又包装起来了
)
}
}
在上面的代码中y
为x(x为promise对象)
成功返回的值,如果y
是一个普通值
-
If/when
x
is fulfilled, fulfillpromise
with the same value. -
If/when
x
is rejected, rejectpromise
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
此时 已经是完成的,那我们直接把resolve
和reject
传递进去, 就会立即执行了,因为是完成的,所以他的值一定是普通值
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'))) {
// ...
}
-
Let
then
bex.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 thex.then
property. Such precautions are important for ensuring consistency in the face of an accessor property, whose value could change between retrievals.
这里的意思是,我们先不判断then
是不是方法,后面再判断。
-
If retrieving the property
x.then
results in a thrown exceptione
, rejectpromise
withe
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)
}
}
-
If
then
is a function, call it withx
asthis
, first argumentresolvePromise
, and second argumentrejectPromise
, where:-
If/when
resolvePromise
is called with a valuey
, run[[Resolve]](promise, y)
. -
If/when
rejectPromise
is called with a reasonr
, rejectpromise
withr
.
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
作为then
的this
实际上就是执行以下代码x.then( y => { resolvePromise(promise2, y, resolve, reject) }, r => reject(r) )
我们会发现代码和上面
x
为promise
时的处理一模一样的-
If both
resolvePromise
andrejectPromise
are called, or multiple calls to the same argument are made, the first call takes precedence, and any further calls are ignored.
即
resolvePromise
和rejectPromise
只能执行其中的一个,因为要符合状态要么是-
pending → fulfilled
-
pending → rejected
-
pending只能改变一次
如果
resolvePromise
和rejectPromise
同时执行了,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) { // ... } }
-
If calling
then
throws an exceptione
,-
If
resolvePromise
orrejectPromise
have been called, ignore it. -
Otherwise, reject
promise
withe
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); } }
-
-
If
then
is not a function, fulfillpromise
withx
.
如果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) {
}