在实现之前需要先理解Promise工作的机制,其实Promise就是一个构造函数,内部有三个状态,分别如下所示:
- pending
- resolved
- rejected
而要想将某个promise实例从初始的pending状态改变为resolved或者rejected状态则必须要通过resolve()或者reject()这两个方法,而需要注意的是promise实例的状态改变是不可逆
的,因此在改变为resolved或者rejected之后后续的改变状态的操作会因此而无效
在Promsie原型对象中含有then、catch、all、race、finally这些方法
在本文章中就先实现promise构造函数以及then还有catch这两个方法
then这个方法可以接受两个参数,一个成功的回调,一个失败的回调。也就是onResolved和onRejected
catch这个方法只可以接受一个参数,失败的回调,也就是onRejected
并且then这个方法,是返回一个新的promise对象,它里面的执行方法也是异步的
触发then的时候,也会有三个可能,一个是状态为resolved时,一个是状态为rejected时,一个是状态为pending时
Promise的结果根据执行的结果返回
首先是promise构造函数的实现,具体实现如下:
function MyPromise(exec) {
this.state = PENDING;
this.value = null;
this.reason = null;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = (value) => {
if (this.state === PENDING) {
this.state = FULFILLED;
this.value = value;
this.onFulfilledCallbacks.forEach(fun => {
fun();
});
}
}
const reject = (reason) => {
if (this.state === PENDING) {
this.state = REJECTED;
this.reason = reason;
this.onRejectedCallbacks.forEach(fun => {
fun();
});
}
}
try {
exec(resolve, reject);
} catch (reason) {
reject(reason);
}
}
其次是promise的then方法实现,由于then方法可以链式调用,因此需要返回一个新的promise实例,具体实现如下:
MyPromise.prototype.then = function (onFulfilled, onRejected) {
if (typeof onFulfilled != 'function') {
onFulfilled = function (value) {
return value;
}
}
if (typeof onRejected != 'function') {
onRejected = function (reason) {
throw reason;
}
}
const promise2 = new MyPromise((resolve, reject) => {
switch (this.state) {
case FULFILLED:
setTimeout(() => {
try {
const x = onFulfilled(this.value);
resolve(x);
} catch (reason) {
reject(reason);
}
}, 0);
break;
case REJECTED:
setTimeout(() => {
try {
const x = onRejected(this.reason);
resolve(x);
} catch (reason) {
reject(reason);
}
}, 0);
break;
case PENDING:
this.onFulfilledCallbacks.push(() => {
setTimeout(() => {
try {
const x = onFulfilled(this.value);
resolve(x);
} catch (reason) {
reject(reason);
}
}, 0);
})
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
const x = onRejected(this.reason);
resolve(x);
} catch (reason) {
reject(reason);
}
}, 0);
})
break;
}
})
return promise2;
}
最后是promise的catch方法实现,由于catch方法用于捕捉错误,因此只需要调用then方法返回一个新的promise实例即可,具体实现如下:
MyPromise.prototype.catch = function(onRejected) {
return this.then(null, onRejected);
};