resolve
resolve 要考虑传入的是 thenable 对象(带有 then 方法的对象)的情况。
class MyPromise {
// ...
static resolve(value) {
if (value instanceof MyPromise) {
return value;
} else if (value && value.then && typeof value.then === "function") {
// thenable 对象
return new MyPromise(value.then);
} else {
return new MyPromise((resolve) => {
resolve(value);
});
}
}
}
reject
reject 不用考虑那么多情况,直接返回一个失败的 promise。
class MyPromise {
// ...
static reject(reason) {
return new MyPromise((resolve, reject) => {
reject(reason);
});
}
}
all/race/allSettled/any
- 返回一个 promise
- 对传入的参数会调用 Array.from 转化成数组
- 对数组元素会调用 Promise.resolve 转换成 promise
all
所有 promise 都成功则 resolve,只要有一个 promise 失败则 reject。
class MyPromise {
// ...
static all(promises) {
const result = [];
let count = 0;
return new MyPromise((resolve, reject) => {
Array.from(promises).forEach((p, index) => {
Promise.resolve(p).then(
(value) => {
result[index] = value;
count++;
if (count === promises.length) {
// 所有 promise 成功则 resolve
resolve(result);
}
},
(reason) => {
// 有一个失败则 reject
reject(reason);
}
);
});
});
}
}
race
将第一个改变状态的 promise 的状态传递给返回的 promise。
class MyPromise {
// ...
static race(promises) {
return new MyPromise((resolve, reject) => {
Array.from(promises).forEach((p, index) => {
Promise.resolve(p).then(
(value) => {
resolve(value);
},
(reason) => {
reject(reason);
}
);
});
});
}
}
allSettled
所有 promise 状态改变后则 resolve。
class MyPromise {
// ...
static allSettled(promises) {
const result = [];
let count = 0;
return new MyPromise((resolve, reject) => {
Array.from(promises).forEach((p, index) => {
Promise.resolve(p).then(
(value) => {
result[index] = { status: "fulfilled", value };
count++;
if (count === promises.length) {
resolve(result);
}
},
(reason) => {
result[index] = { status: "rejected", reason };
count++;
if (count === promises.length) {
resolve(result);
}
}
);
});
});
}
}
any
跟 all 相反,所有 promise 都失败则 reject,只要有一个 promise 成功则 resolve。
class MyPromise {
// ...
static any(promises) {
let count = 0;
return new MyPromise((resolve, reject) => {
Array.from(promises).forEach((p) => {
Promise.resolve(p).then(
(value) => {
resolve(value);
},
() => {
count++;
if (count === promises.length) {
reject(new AggregateError("All promises were rejected"));
}
}
);
});
});
}
}