参考
代码
// 解析中间promise(promise2)
const resolvePromise = (x, promise2, resolve, reject) => {
// 不能循环引用Promise
if (x === promise2) {
const err = new TypeError("不能循环引用promise!");
return reject(err);
}
// 如果x为对象或者函数,则做进一步判断,
// 否则直接resolve(x)
if (x != null && (typeof x === "object" || typeof x === "function")) {
// 定义called,用于标记是否已调用过resolve或reject
let called = false;
// 尝试调用
try {
// 因为then可能为getter,所以不能直接调x.then,
const then = x.then;
// 为了兼容其他Promise实现,不能直接用instanof对x进行判断
// 只要x是一个thenable的对象即可,否则,直接resolve(x)
if (typeof then === "function") {
then.call(
x,
(y) => {
if (called) return;
called = true;
// 递归解析
resolvePromise(y, promise2, resolve, reject);
},
(reason) => {
if (called) return;
called = true;
reject(reason);
}
);
} else {
resolve(x);
}
} catch (err) {
// 如果过程中出错,则reject(err)
if (called) return;
called = true;
reject(err);
}
} else {
resolve(x);
}
};
// 状态枚举
const STATUS = {
PENDING: Symbol("PENDING"),
RESOLVED: Symbol("FULFILLED"),
REJECTED: Symbol("REJECTED"),
};
// MyPromise
class MyPromise {
// 构造方法
constructor(executor) {
// 初始化状态为Pending
this.status = STATUS.PENDING;
// 初始化value和reason
this.value = undefined;
this.reason = undefined;
// 初始化回调队列
this.onResolvedCallbacks = [];
this.onRejectedCallbacks = [];
// 实现resolve
const resolve = (value) => {
// 如果状态不为pending,则返回
if (this.status !== STATUS.PENDING) return;
// 将状态改变为fulfilled
this.status = STATUS.RESOLVED;
// 设置value
this.value = value;
// 执行resolve后的回调函数
this.onResolvedCallbacks.forEach((callback) => callback());
};
// 实现reject,同resolve
const reject = (reason) => {
if (this.status !== STATUS.PENDING) return;
this.status = STATUS.REJECTED;
this.reason = reason;
this.onRejectedCallbacks.forEach((callback) => callback());
};
// 执行
try {
executor(resolve, reject);
} catch (err) {
reject(err);
}
}
// MyPromise.prototype.then
then(onResolved, onRejected) {
// 实现值穿透
if (typeof onResolved !== "function")
onResolved = (value) => {
return value;
};
if (typeof onRejected !== "function")
onRejected = (reason) => {
throw reason;
};
// 创建新的promise
const promise2 = new MyPromise((resolve, reject) => {
// 区分状态
switch (this.status) {
// promise位于pending状态时,暂时还无法确定结果,
// 所以先将resolve和reject的回调函数添加到回调数组中
case STATUS.PENDING:
this.onResolvedCallbacks.push(() => {
// 模拟异步
setTimeout(() => {
try {
// 获取then的返回值
const x = onResolved(this.value);
// 对返回值进行解析
resolvePromise(x, promise2, resolve, reject);
} catch (err) {
reject(err);
}
}, 0);
});
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
const x = onRejected(this.reason);
resolvePromise(x, promise2, resolve, reject);
} catch (err) {
reject(err);
}
}, 0);
});
break;
// promise位于fulfilled状态时,直接执行onResolved
case STATUS.RESOLVED:
setTimeout(() => {
try {
const x = onResolved(this.value);
resolvePromise(x, promise2, resolve, reject);
} catch (err) {
reject(err);
}
}, 0);
break;
// promise位于rejected状态时,直接执行onRejected
case STATUS.REJECTED:
setTimeout(() => {
try {
const x = onRejected(this.reason);
resolvePromise(x, promise2, resolve, reject);
} catch (err) {
reject(err);
}
}, 0);
break;
}
});
// 返回该promise
return promise2;
}
// MyPromise.prototype.catch
catch(onRejected) {
return this.then(null, onRejected);
}
// MyPromise.prototype.finally
finally(onFinally) {
return this.then(onFinally, onFinally);
}
// MyPromise.all
static all(promises) {
let resolvedCount = 0;
const length = promises.length,
result = new Array(length),
resolvedCountAdd = (index, value, resolve) => {
resolvedCount++;
result[index] = value;
if (resolvedCount === length) {
resolve(result);
}
};
return new MyPromise((resolve, reject) => {
for (let i = 0; i < length; i++) {
promises[i].then(
(value) => {
resolvedCountAdd(i, value, resolve);
},
(reason) => {
reject(reason);
}
);
}
});
}
// MyPromise.any
static any(promises) {
let rejectedCount = 0;
const length = promises.length,
result = new Array(length),
rejectedCountAdd = (index, reason, reject) => {
rejectedCount++;
result[index] = reason;
if (rejectedCount === length) {
reject(result);
}
};
return new MyPromise((resolve, reject) => {
for (let i = 0; i < length; i++) {
promises[i].then(
(value) => {
resolve(value);
},
(reason) => {
rejectedCountAdd(i, reason, reject);
}
);
}
});
}
// MyPromise.allSettled
static allSettled(promises) {
let processedCount = 0;
const length = promises.length,
result = new Array(length),
processedCountAdd = (index, data, resolve) => {
processedCount++;
result[index] = data;
if (processedCount === length) {
resolve(result);
}
};
return new MyPromise((resolve) => {
for (let i = 0; i < length; i++) {
promises[i].then(
(value) => {
processedCountAdd(i, value, resolve);
},
(reason) => {
processedCountAdd(i, reason, resolve);
}
);
}
});
}
// MyPromise.race
static race(promises) {
const length = promises.length;
return new MyPromise((resolve, reject) => {
for (let i = 0; i < length; i++) {
promises[i].then(
(value) => {
resolve(value);
},
(reason) => {
reject(reason);
}
);
}
});
}
// MyPromise.resolve
static resolve(value = undefined) {
// 如果不是对象,则直接返回resolve(value)
if (!(value instanceof Object)) {
return new MyPromise((resolve) => {
resolve(value);
});
}
// 如果是promise实例,则原封不动的返回
if (value instanceof MyPromise) {
return value;
}
// 如果是thenable的对象,则包装后返回,
// 否则直接返回resolve(value)
const then = value.then;
if (typeof then === "function") {
return new Promise(then.bind(value));
} else {
return new MyPromise((resolve) => {
resolve(value);
});
}
}
// MyPromise.reject
static reject(reason) {
return new MyPromise((resolve, reject) => {
reject(reason);
});
}
// 使用 promises-aplus-tests 进行测试
static deferred() {
const defer = {};
defer.promise = new MyPromise((resolve, reject) => {
defer.resolve = resolve;
defer.reject = reject;
});
return defer;
}
}
module.exports = MyPromise;
验证
新建文件MyPromise.js,复制以上代码到其中,再执行以下命令:
npm i promises-aplus-tests -g
promises-aplus-tests MyPromise.js
# ...
# 872 passing (18s)