/**
* Promise构造函数
* executor: 内部同步执行的函数(resolve, reject) => {}
* new Promise((resolve, reject) => {
* setTimeout(() => { resolve(42); }, 1000);
* })
*/
function Promise2(executor) {
// 初始状态
this.PromiseState = "pending";
// 初始结果
this.PromiseResult = null;
// 保存回调函数
this.callbacks = [];
const self = this;
// resolve函数
function resolve(value) {
// 判断状态,让Promise对象只能修改一次
if(self.PromiseState !== "pending") return;
// 修改状态
self.PromiseState = "fulfilled";
// 修改结果
self.PromiseResult = value;
// 调用回调函数
setTimeout(() => {
self.callbacks.forEach(element => {
element.onResolved(value);
});
});
}
// reject函数
function reject(reason) {
// 判断状态,让Promise对象只能修改一次
if(self.PromiseState !== "pending") return;
// 修改状态
self.PromiseState = "rejected";
// 修改结果
self.PromiseResult = reason;
// 调用回调函数
setTimeout(() => {
self.callbacks.forEach(element => {
element.onRejected(reason);
});
});
}
// 同步调用执行器函数
try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
Promise2.prototype.then = function(onResolved, onRejected) {
if(typeof onResolved !== "function") {
onResolved = value => value;
}
if(typeof onRejected !== "function") {
onRejected = reason => {
throw new Error(reason);
}
}
// 固定返回一个Promise对象,这里我们称为newPro对象,供下一环节使用
// 注意这里是箭头函数,所以里面this指向oldPro对象(最初创建的Promise对象,称为oldPro)
return new Promise2((resolve, reject) => {
function handle(callback) {
try {
let result = callback(this.PromiseResult);
// 当result为Promise对象,这里我们称为resultPro,这个resultPro是外部自定义的
if(result instanceof Promise) {
// then方法将v函数压入resultPro对象的callbacks数组里,
// 当resultPro对象执行resolve函数时触发callbacks数组执行v函数,
// 执行v函数触发newPro对象的resolve函数,继而触发下一环节Promise对象执行onResolved函数
result.then(
// 该onResolved函数这里我们称为v函数,参数值为resultPro对象执行resolve函数时传入的值
v => {
// resolve为Promise构造函数内置函数
resolve(v);
},
r => {
reject(r);
}
);
} else {
// 触发newPro对象的resolve函数,并将result值向下一环节Promise对象的onResolved函数传递
resolve(result);
}
} catch (error) {
reject(error);
}
}
if(this.PromiseState === "pending") {
// 将then方法的onResolved函数压入oldPro对象的callbacks数组,供oldPro执行resolve方法调用
this.callbacks.push({
onResolved: (value) => {
handle.call(this, onResolved);
},
onRejected (reason) {
handle.call(this, onRejected);
}
});
}
if(this.PromiseState === "fulfilled") {
setTimeout(() => {
handle(onResolved);
})
}
if(this.PromiseState === "rejected") {
setTimeout(() => {
handle(onRejected);
})
}
});
}