class Promise {
// 构造方法
constructor(executor) {
// resolve函数---里面还需要声明形参去接收实参
// 给实例对象的身上添加属性,直接通过this强行复制的方式去添加,这里的this就指的是新创建(new出来的)的实例对象
this.PromiseState = "pending";
this.PromiseResult = null;
// 声明属性用来保存then方法中的回调函数
this.callBacks = [];
// 解决下方this指向问题,可以在这里先把this的指向保存下来
const that = this;
// const _this = this;
// const self = this; //三种保存this值的常见写法
function resolve(data) {
// 判断Promise实例对象的状态(状态变为成功或者失败就不能再次改动)
if (that.PromiseState !== "pending") return;
// 1.修改对象的状态(PromiseState)
// 注意:这里的this指向的不是新new出来实例对象,而是指向全局的Window对象(所以要提前把this的值保存下来)
that.PromiseState = "fulfilled"; //或者为resolve(意思都一样)
// 2.修改对象结果值(PromiseResult)
that.PromiseResult = data;
// 调用成功的回调函数
that.callBacks.forEach((item) => {
setTimeout(() => {
//加定时器让回调函数变为异步操作
item.onResolved(data); //forEach不会遍历数组元素为empty(空)的数组,所以加不加判断条件都不会影响性能
});
});
}
// reject函数---里面还需要声明形参去接收实参
function reject(data) {
// 判断Promise实例对象的状态(状态变为成功或者失败就不能再次改动)
if (that.PromiseState !== "pending") return;
// 1.修改对象的状态(PromiseState)
that.PromiseState = "rejected";
// 2.修改对象结果值(PromiseResult)
that.PromiseResult = data;
// 调用失败的回调函数
that.callBacks.forEach((item) => {
setTimeout(() => {
item.onRejected(data);
});
});
}
// 同步调用(执行器函数-executor)
try {
executor(resolve, reject);
} catch (error) {
// 修改Promise实例对象的状态为失败
reject(error);
}
}
// then方法的封装
then(onResolved, onRejected) {
const that = this;
// 判断回调函数参数是否传递的是一个函数,如果不是一个函数,就给他添加一个默认值---值为函数
if (typeof onResolved !== "function") {
onResolved = (value) => value; //value=>{return value} ES6
}
if (typeof onRejected !== "function") {
onRejected = (reason) => {
throw reason;
};
}
return new Promise((resolve, reject) => {
// 封装函数
function callBack(type) {
try {
// 在这里还有传入实参,实参为Promise实例对象成功之后的结果值
// 获取成功函数的执行结果
let result = type(that.PromiseResult); //this指向有问题,在函数内部直接调用,指的是Window
// 判断result是不是Promise的实例对象
if (result instanceof Promise) {
// 如果是Promise类型的对象
result.then(
(v) => {
resolve(v);
},
(r) => {
reject(r);
}
);
} else {
// 结果的对象状态为成功
resolve(result);
}
} catch (error) {
reject(error);
}
}
// 调用回调函数并且加上判断条件(判断Promise实例对象身上的PromiseState属性)
// 这里的this指的是Promise实例对象(函数包裹第一层的时候里面的this指向的是实例对象,第二层指向的是Window,除非第二层写箭头函数,箭头函数没有自己的this,所以this指向的就是外部的定义时的this,就是Promise实例对象),标准说法为构造函数中的this,后期谁调用指谁
if (this.PromiseState === "fulfilled") {
setTimeout(() => {
//加定时器更改回调函数为异步执行
callBack(onResolved);
});
}
if (this.PromiseState === "rejected") {
setTimeout(() => {
callBack(onRejected);
});
}
// 判断pending状态
if (this.PromiseState === "pending") {
// 保存回调函数
this.callBacks.push({
// ES6简写
// onResolved, //相当于onResolved:onResolved
// onRejected, //相当于onRejected:onRejected
onResolved: function () {
callBack(onResolved);
},
onRejected: function () {
callBack(onRejected);
},
});
}
});
}
// catch方法的封装
catch(onRejected) {
return this.then(undefined, onRejected);
}
// resolve方法的封装
static resolve(value) {
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(
(v) => {
resolve(v);
},
(r) => {
reject(r);
}
);
} else {
resolve(value);
}
});
}
// reject方法的封装
static reject(reason) {
return new Promise((resolve, reject) => {
reject(reason);
});
}
// all方法的封装
static all(promises) {
// 声明一个变量,用来判断promises数组里的Promise对象状态十分都为成功
let count = 0;
// 声明一个变量,用来保存成功的结果,结果是一个数组
let arr = [];
// 结果为Promise的对象
return new Promise((resolve, reject) => {
// 遍历---这里的变量i必须使用let声明,不然i会被全局污染
for (let i = 0; i < promises.length; i++) {
// parmises[i]是其中的一个Promise对象
promises[i].then(
(v) => {
// 得知对象的状态是成功的
// 如果每一个Promise对象的状态都是成功的,才能去执行resolve函数
count++;
// 将当前Promise对象的结果存入到数组中
// arr.push(v);这种方法保存结果有点bug,异步的时候会导致顺序跟数组里面传进来Promise对象顺序不一致
arr[i] = v;
// 判断:如果count的值等于promises数组的长度,就说明这个promises数组里的Promise数组状态都为成功
if (count === promises.length) {
// 修改状态
resolve(arr);
}
},
(r) => {
reject(r);
}
);
}
});
}
// race方法的封装
static race(promises) {
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
promises[i].then(
(v) => {
// 修改返回对象的状态为成功
resolve(v);
},
(r) => {
// 修改返回对象的状态为失败
reject(r);
}
);
}
});
}
}