附上源码
最后附上源代码,经过promises-aplus-tests库进行promiseA+规范用例测试,所有用例Pass
const FULFILLED_STATUS = "fulfilled";
const REJECTED_STATUS = "rejected";
const PENDING_STATUS = "pending";
function resolvePromise(promise, x, resolve, reject) {
if (promise === x) {
// 避免循环引用
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'));
}
let called;
if (x !== null && (["function", "object"].includes(typeof x))) {
// 判断当前x的类型是否为Promise
try {
let then = x.then;
if (typeof then === "function") {
then.call(x, y => {
if (called) return;
called = true;
// y 仍为一个promise 需要递归调用
resolvePromise(promise, y, resolve, reject);
}, r => {
if (called) return;
called = true;
reject(r);
})
} else {
resolve(x);
}
} catch (e) {
if (called) return;
called = true;
reject(e);
}
} else {
resolve(x);
}
}
class MyPromise {
constructor(executor) {
this.status = PENDING_STATUS;
this.value = undefined;
this.reason = undefined;
this.onFulfillCallbacks = [];
this.onRejectCallbacks = [];
const resolve = (value) => {
if (this.status === PENDING_STATUS) {
this.status = FULFILLED_STATUS;
this.value = value;
this.onFulfillCallbacks.forEach(fn => fn());
}
}
const reject = (reason) => {
if (this.status === PENDING_STATUS) {
this.status = REJECTED_STATUS;
this.reason = reason;
this.onRejectCallbacks.forEach(fn => fn());
}
}
try {
executor(resolve, reject);
} catch (e) {
reject(e);
}
}
// return Promise
then(onFulfilled, onRejected) {
// 解决链式调用问题,then 的值传递
onFulfilled = typeof onFulfilled === "function" ? onFulfilled : (value) => value;
onRejected = typeof onRejected === "function" ? onRejected : (reason) => { throw reason };
let promise2 = new MyPromise((resolve, reject) => {
if (this.status === FULFILLED_STATUS) {
// setTimeout 宏任务 延后执行 为了可以获取到promise2
setTimeout(() => {
try {
let x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
} else if (this.status === REJECTED_STATUS) {
setTimeout(() => {
try {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
} else if (this.status === PENDING_STATUS) {
this.onFulfillCallbacks.push(() => {
setTimeout(() => {
try {
let x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
})
this.onRejectCallbacks.push(() => {
setTimeout(() => {
try {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
})
}
});
return promise2;
}
}
// promiseA+规范测试库来验证你的promise
MyPromise.defer = MyPromise.deferred = function () {
let dfd = {};
dfd.promise = new MyPromise((resolve, reject) => {
dfd.resolve = resolve;
dfd.reject = reject;
});
return dfd;
}
try {
module.exports = MyPromise;
} catch (err) { }