我写这篇文章不打算介绍Promise产生的缘由以及它解决的问题,我只是想写一篇关于实现本身Promise的文章。若是代码以及逻辑有什么不对的地方,请你们指出来。就这些,开始正题。数组
前提:咱们要知道Promise是基于Promises/A+规范的。其中好多变量和方法名都是从这里来的。 咱们先从Promise的使用开始,写几个测试例子。promise
let promise = new Promise((resolve, reject) =>{
// console.log("1");
// resolve("成功");
// reject("失败");
// console.log("2");// 第一步
// reject("失败");
// resolve("成功");// 第二步
// setTimeout(() => {
// resolve("success");
// }, 2000);
throw new Error("手动抛出错误");// 第四步
});
promise.then((value) => {
console.log("then第一个方法:"+value);
}, (err) => {
console.log("then第二个方法:"+err);
})
promise.then((value) => {
console.log("then第一个方法:"+value);
}, (err) => {
console.log("then第二个方法:"+err);
})
console.log("3");
复制代码
第一步输出缓存
第二步输出bash
第三步输出异步
第四步输出函数
最后输出“成功”说明 then是异步执行的测试
根据以上几个例子咱们能够推出如下几点内容:ui
这么一大坨东西,看着有点乱。咱们就根据咱们得出的结论开始写属于本身的Promise。写的过程当中思路慢慢就清晰了。this
let myPromise = function (executor) {
let self = this;//缓存一下this
self.status = 'pending';// 状态管理 状态的变化只能由pending变为resolved或者rejected。一件事情不能既成功又失败。因此resolved和rejected不能相互转化。
self.value = undefined;// 成功后的值 传给resolve
self.reason = undefined;//失败缘由 传给reject
self.onResolvedCallbacks = [];// 存放then中成功的回调
self.onRejectedCallbacks = []; // 存放then中失败的回调
// 这里说明一下,第三步使用定时器。执行完 new Promise 以后,会执行then方法,此时会把then中的方法缓存起来,并不执行:此时状态仍是pending。等到定时器2秒以后,执行
// resolve|reject 时,而是依次执行存放在数组中的方法。 参考发布订阅模式
function resolve(value) {
// pending => resolved
if (self.status === 'pending') {
self.value = value;
self.status = 'resolved';
// 依次执行缓存的成功的回调
self.onResolvedCallbacks.forEach(fn => fn(self.value));
}
}
function reject(reason) {
// pending => rejected
if (self.status === 'pending') {
self.value = value;
self.status = 'rejected';
// 依次执行缓存的失败的回调
self.onRejectedCallbacks.forEach(fn => fn(self.reason));
}
}
try {
//new Promise 时 executor执行
executor(resolve, reject);
} catch (error) {
reject(error);// 当executor中执行有异常时,直接执行reject
}
}
// 每一个Promise实例上都有then方法
Promise.prototype.then = function (onFulfilled, onRejected) {
let self = this;
// 执行了 resolve
if (self.status === 'resolved') {
// 执行成功的回调
onFulfilled(self.value);
}
// 执行了 reject
if (self.status === 'rejected') {
// 执行失败的回调
onRejected(self.reason);
}
// new Promise中能够支持异步行为 当既不执行resolve又不执行reject时 状态是默认的等待态pending
if (self.status === 'pending') {
// 缓存成功的回调
self.onResolvedCallbacks.push(onFulfilled);
// 缓存失败的回调
self.onRejectedCallbacks.push(onRejected);
}
};
复制代码
说明一下:这是最简版,由于Promise的强大之处是链式调用。咱们这个只是雏形,因为时间关系。咱们先到这里。下一次咱们基于这个雏形实现符合Promises/A+规范的完整版。spa
第一次发表文章,但愿各位大虾多多支持。