参考资料
本文参考资料 MDN
代码
const PENDING = 'pending';
const RESOLVED = 'resolved';
const REJECTED = 'rejected';
/**
* Promise 构造函数
* @param {*} excutor 执行器方法(同步执行)
*/
function MyPromise(excutor) {
this.status = PENDING; //给 promise 对象指定 status 属性,初始值为 pending
this.data = undefined; // 给 promise 对象指定一个用于存储结果的属性
this.callbacks = []; // 每个元素的结构为 {onResolved(){}, onRejected(){}}
function resolve(value) {
// 如果当前状态不是 pending,直接结束
if (this.status !== PENDING) {
return;
}
// 将状态改为 resolved
this.status = RESOLVED;
// 保存 value 数据
this.data = value;
// 如果有待执行的 callback 函数,异步执行回调 onResolved (用setTimeout执行异步)
if (this.callbacks.length > 0) {
this.callbacks.forEach(callbacksObj => { //放到队列中执行所有成功的回调
setTimeout(() => {
callbacksObj.onResolved(value);
});
});
}
}
function reject(reason) {
// 如果当前状态不是 pending,直接结束
if (this.status !== PENDING) {
return;
}
// 将状态改为 rejected
this.status = REJECTED;
//保存 reason 数据
this.data = reason;
//如果有待执行的 callback 函数,异步执行回调函数 onRejected(用setTimeout执行异步)
if (this.callbacks.length > 0) {
this.callbacks.forEach(callbacksObj => {
setTimeout(() => {
callbacksObj.onRejected(reason);
});
});
}
}
//立即同步执行 excutor,如果执行器函数抛出异常,promise 对象变为 rejected 状态 (直接调用reject方法即可)
try {
excutor(resolve.bind(this), reject.bind(this));
} catch (error) {
reject(error);
}
}
/**
* Promise 原型对象的 then()
* @param {*} onResolved 指定成功的回调函数
* @param {*} onRejected 指定失败的回调函数
* @return 返回一个新的 Promise 对象,返回的 Promise 的结由 onResolved/onRejected 的执行结果决定
*/
MyPromise.prototype.then = function (onResolved, onRejected) {
onResolved = typeof onResolved === 'function' ? onResolved : value => value;
// 指定默认的失败回调(实现错误/异常传透)
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason; };
return new MyPromise((resolve, reject) => {
/**
* 调用指定的回调函数处理,根据执行结果,改变 return 的 promise 状态
*
* 1. 如果回调函数抛出异常,return 的 promise 就会失败,reason 就是 error
* 2. 如果回调函数返回的不是 promise,return 的 promise 就会成功,value 就是返回的值
* 3. 如果回调函数返回的是一个 promise,return 的 promise 的结果就是这个 promise 的结果
*
* @param {*} callback
*/
const hander = (callback) => {
try {
const result = callback(this.data);
if (result instanceof MyPromise) { // 3.
result.then(resolve, reject); // 2.
} else {
resolve(result);
}
} catch (error) { //1.
reject(error);
}
};
switch (this.status) {
case PENDING: // 如果当前是 pending 状态,将回调函数保存起来,等 status 改变后在执行
this.callbacks.push(
{
onResolved: value => hander(onResolved),
onRejected: reason => hander(onRejected)
});
break;
case RESOLVED: // 如果当前是 resolved 状态,异步执行 onResolved,并改变 return 的 promise 状态
setTimeout(() => {
hander(onResolved);
});
break;
case REJECTED: // 如果当前是 rejected 状态,异步执行 onRejected,并改变 return 的 promise 状态
setTimeout(() => {
hander(onRejected);
});
break;
default:
break;
}
});
};
/**
* Promise 原型对象的 catch()
* @param {*} onRejected 指定失败的回调函数
* @return 返回一个新的 Promise 对象
*/
MyPromise.prototype.catch = function (onRejected) {
return this.then(undefined, onRejected);
};
/**
* Promsie 函数对象方法(静态方法)
* @param {*} value
* @return 返回一个指定结果的成功的 Promise 对象
*/
MyPromise.resolve = function (value) {
return new MyPromise((resolve, reject) => {
if (value instanceof MyPromise) {
value.then(resolve, reject);
} else {
resolve(value);
}
});
};
/**
* Promise 函数对象方法(静态方法)
* @param {*} reason 失败的原因
* @return 返回一个指定 reason 的失败的 Promise 对象
*/
MyPromise.reject = function (reason) {
return new MyPromise((resolve, reject) => {
reject(reason);
});
};
/**
* Promise 函数对象的 all 方法(静态方法)
* @param {*} myPromises
* @return 返回一个 promise 只有当所有的 promise 都成功时才成功,否则只要有一个失败则失败
*/
MyPromise.all = function (myPromises) {
//用来保存所有成功 value 的数组
const values = Array(myPromises.length);
//用来保存成功 promise 的数量
let resolvedCount = 0;
return new MyPromise((resolve, reject) => {
// 遍历获取每个Promise的结果
myPromises.forEach((p, index) => {
//p成功,将成功的 value 保存到 values 中
//MyPromise.resolve(p) 说明:myPromises中的的元素有可能不是一个Promise对象,
//用 MyPromise.resolve 将其包装成一个promise对象
MyPromise.resolve(p).then(value => {
resolvedCount++;
values[index] = value;
//如果全部成功了,将 return 的 promise 改为成功
if (resolvedCount === myPromises.length) {
resolve(values);
}
}, reason => { //只要有一个失败了,return 的 promise 就失败
reject(reason);
});
});
});
};
/**
* Promise 函数对象 race 方法 (类里面静态方法)
* @param {*} myPromises
* @return 返回一个 promise,其结果由第一个完成的 promise 的结果决定
*/
MyPromise.race = function (myPromises) {
return new MyPromise((resolve, reject) => {
//返回第一个执行完成的 promise 的结果
myPromises.forEach((p) => {
//MyPromise.resolve(p) 说明:myPromises中的的元素有可能不是一个Promise对象,
//用 MyPromise.resolve 将其包装成一个promise对象
MyPromise.resolve(p).then(value => {
resolve(value);
}, reason => {
reject(reason);
});
});
});
};
网友评论