手写Promise
构造函数
then
catch
Promise.resolve()
Promise.reject()
Promise.reject = function (err) {
return new Promise((resolve, reject) => {
reject(err);
});
};
Promise.all()
Promise.all()
返回一个合成的 Promise 实例。只有当每个包含的 Promise 实例都解决(fulfilled)后才解决(fulfilled),如果有一个包含的 Promise 实例拒绝(rejected)了,则合成的 Promise 也会拒绝(rejected)。
Promise.all = function (promiseList) {
let count = 0;
let result = [];
const length = promiseList.length;
return new Promise((resolve, reject) => {
promiseList.forEach(
(p, index) => {
p.then(res => {
result[index] = res;
count++;
if (count === length) {
resolve(result);
}
});
},
err => {
reject(err);
}
);
});
};
Promise.race()
Promise.race()
返回一个合成的 Promise 实例。其会返回这一组中最先解决(fulfilled)或拒绝(rejected)的 Promise 实例的返回值。
Promise.race = function (promiseList) {
return new Promise((resolve, reject) => {
promiseList.forEach(promise => {
promise.then(
res => {
resolve(res);
},
err => {
reject(err);
}
);
});
});
};
Promise.any()
Promise.any()
相当于 Promise.all()
的反向操作,同样返回一个合成的 Promise 实例。只要其中包含的任何一个 Promise 实例解决(fulfilled)了,合成的 Promise 就解决(fulfilled)。
只有当每个包含的 Promise 都拒绝(rejected)了,合成的 Promise 才拒绝(rejected)。
Promise.any = function (promiseList) {
let count = 0;
const res = [];
const length = promiseList.length;
return new Promise((resolve, reject) => {
promiseList.forEach((promise, index) => {
promise.then(
res => {
resolve(res);
},
err => {
count++;
res[index] = err;
if (count === length) {
reject(err);
}
}
);
});
});
};
Promise.allSettled()
Promise.allSettled()
返回一个合成的 Promise 实例。等到所有包含的每个 Promise 实例都返回结果落定时,不管是解决(fulfilled)还是拒绝(rejected),合成的 Promise 才会结束。一旦结束,状态总是 fulfilled。
其返回的是一个对象数组,每个对象表示对应的 Promise 结果。
对于每个结果对象,都有一个 status 字符串。如果它的值为 fulfilled,则结果对象上存在一个 value 。如果值为 rejected,则存在一个 reason 。
Promise.allSettled = function (promiseList) {
const result = [];
let count = 0;
return new Promise((resolve, reject) => {
promiseList.forEach((promise, index) => {
promise.then(
val => {
result[index] = {
status: "fulfilled",
value: val,
};
count++;
if (count === promiseList.length) {
resolve(result);
}
},
err => {
result[index] = {
status: "rejected",
reason: err,
};
count++;
if (count === promiseList.length) {
resolve(result);
}
}
);
});
});
};
应用场景
PromisePool
async function promisePool(functions, n) {
const resolved = [];
const queue = new Set();
for (const task of functions) {
const x = task().then(res => {
resolved.push(res);
queue.delete(x);
});
queue.add(x);
if (queue.size >= n) await Promise.race(queue);
}
await Promise.allSettled(queue);
return resolved;
}