完整代码如下:
// 定义三个状态
const PENDING = 'pending'; // 等待
const FULFILLED = 'fulfilled'; // 成功
const REJECTED = 'rejected'; // 失败
class MyPromise {
constructor(executor) {
try {
executor(this.resolve, this.reject);
} catch (e) {
this.reject(e)
}
}
// 定义一个表示状态的属性
status = PENDING;
// 定义两个实例属性,表示成功之后的值和失败后的原因
value = undefined;
reason = undefined;
// 成功回调
successCallback = [];
// 失败回调
failedCallback = [];
// 两个属性,这里定义成箭头函数,是因为我们在使用的时候是直接调用,
// 而普通函数内部this的指向window或者是undefined,定义成箭头函数使函数内部this指向指向类实例对象
resolve = value => {
// 如果状态不是等待,阻止程序向下进行
if (this.status !== PENDING) return
// 更改状态为成功
this.status = FULFILLED
// 保存成功的值
this.value = value;
// 判断成功回调是否存在,如果存在就调用
// this.successCallback && this.successCallback(this.value);
while (this.successCallback.length) {
this.successCallback.shift()();
}
}
reject = reason => {
// 如果状态不是等待,阻止程序向下进行
if (this.status !== PENDING) return
// 更改状态为失败
this.status = REJECTED
// 保存失败的原因
this.reason = reason;
// 判断失败回调是否存在,存在就调用
// this.failedCallback && this.failedCallback(this.reason);
while (this.failedCallback.length) {
this.failedCallback.shift()();
}
}
then(successCallback, failedCallback) {
// 可选参数
successCallback = successCallback ? successCallback : value => value;
failedCallback = failedCallback ? failedCallback : reason => {
throw reason
};
let promise2 = new Promise((resolve, reject) => {
// 状态判断
if (this.status === FULFILLED) {
setTimeout(() => {
try {
// 定义成功回调返回值,传给下一个then的成功回调
let successRtn = successCallback(this.value);
// 判断 x 的值是普通值还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promsie对象返回的结果
// 再根据promise对象返回的结果 决定调用resolve 还是调用reject
// 执行resolve方法,相当于把返回值传递给下一个then的成功回调函数
resolvePromise(promise2, successRtn, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
} else if (this.status === REJECTED) {
setTimeout(() => {
try {
let failedRtn = failedCallback(this.reason);
resolvePromise(promise2, failedRtn, resolve, reject);
} catch (e) {
reject(e)
}
}, 0);
} else {
// 等待,需要将成功回调和失败回调存储起来,等待需要执行的时候才执行
this.successCallback.push(() => {
setTimeout(() => {
try {
let successRtn = successCallback(this.value);
resolvePromise(promise2, successRtn, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
this.failedCallback.push(() => {
setTimeout(() => {
try {
let failedRtn = failedCallback(this.reason);
resolvePromise(promise2, failedRtn, resolve, reject);
} catch (e) {
reject(e)
}
}, 0);
});
}
});
return promise2;
};
catch (failCallback) {
this.then(undefined, failCallback)
};
finally(callback) {
return this.then(value => {
return MyPromise.resolve(callback()).then(() => value);
}, reason => {
return MyPromise.resolve(callback()).then(() => {
throw reason
})
})
};
static all(array) {
let result = [];
// 用于判断当前执行值是否等于数组长度,相等时才执行resolve()
let idx = 0;
return new MyPromise((resolve, reject) => {
// 添加元素方法
function addElement(index, value) {
result[index] = value;
idx++;
if (idx === array.length) {
resolve(result)
}
}
for (let i = 0; i < array.length; ++i) {
let cur = array[i];
// 判断cur是否是普通值,普通值直接进入result数组,
// promise对象就执行它,调用then方法,执行成功则添加到result数组,如果失败
if (cur instanceof MyPromise) {
// promise对象
cur.then(value => addElement(i, value), reason => reject(reason))
} else {
// 普通值
addElement(i, array[i]);
}
}
})
}
static race(array) {
return new MyPromise((resolve, reject) => {
for (let i = 0; i < array.length; ++i) {
let cur = array[i];
if (cur instanceof MyPromise) {
cur.then(resolve, reject);
} else {
resolve(cur)
}
}
})
}
static resolve(e) {
if (e instanceof MyPromise) {
return e;
} else {
return new MyPromise(resolve => resolve(e))
}
}
}
function resolvePromise(promise2, e, resolve, reject) {
if (promise2 === e) {
return reject(new TypeError("Chaining cycle detected for promise #"))
}
if (e instanceof MyPromise) {
// promise对象
// e.then((value) => {
// resolve(value)
// }, (reason) => {
// reject(reason)
// })
// 简化代码
e.then(resolve, reject);
} else {
//普通值
resolve(e);
}
}
module.exports = MyPromise;