JavaScript中Promise.all和Promise.race的实现原理与使用

Promise.all
和 Promise.race
是 JavaScript 中用于处理多个 Promise 的两个重要方法。它们分别用于不同的场景,下面我将详细解释它们的实现原理。
1. Promise.all
Promise.all
接收一个 Promise 数组,并返回一个新的 Promise。这个新的 Promise 在所有输入的 Promise 都成功完成时才会被 resolve,resolve 的值是一个数组,包含了所有输入 Promise 的 resolve 值。如果其中任何一个 Promise 被 reject,那么返回的 Promise 会立即被 reject,并且 reject 的原因是第一个被 reject 的 Promise 的原因。
实现代码:
Promise.myAll = function(promises) {
return new Promise((resolve, reject) => {
if (!Array.isArray(promises)) {
return reject(new TypeError('Arguments must be an array'));
}
let results = [];
let completedCount = 0;
if (promises.length === 0) {
return resolve(results);
}
promises.forEach((promise, index) => {
Promise.resolve(promise).then(
value => {
results[index] = value;
completedCount++;
if (completedCount === promises.length) {
resolve(results);
}
},
reason => {
reject(reason);
}
);
});
});
};
使用示例:
const p1 = Promise.resolve(1);
const p2 = Promise.resolve(2);
const p3 = Promise.resolve(3);
Promise.myAll([p1, p2, p3]).then(values => {
console.log(values); // [1, 2, 3]
});
const p4 = Promise.reject('Error');
Promise.myAll([p1, p2, p4]).catch(reason => {
console.log(reason); // 'Error'
});
2. Promise.race
Promise.race
也接收一个 Promise 数组,并返回一个新的 Promise。这个新的 Promise 会在数组中第一个 Promise 完成(无论是 resolve 还是 reject)时立即完成,并且它的值或原因与第一个完成的 Promise 相同。
实现代码:
Promise.myRace = function(promises) {
return new Promise((resolve, reject) => {
if (!Array.isArray(promises)) {
return reject(new TypeError('Arguments must be an array'));
}
promises.forEach(promise => {
Promise.resolve(promise).then(
value => {
resolve(value);
},
reason => {
reject(reason);
}
);
});
});
};
使用示例:
const p1 = new Promise((resolve) => setTimeout(() => resolve(1), 1000));
const p2 = new Promise((resolve) => setTimeout(() => resolve(2), 500));
const p3 = new Promise((resolve) => setTimeout(() => resolve(3), 2000));
Promise.myRace([p1, p2, p3]).then(value => {
console.log(value); // 2
});
const p4 = new Promise((resolve, reject) => setTimeout(() => reject('Error'), 500));
Promise.myRace([p1, p4]).catch(reason => {
console.log(reason); // 'Error'
});
总结
Promise.all
用于等待所有 Promise 完成,并且只有在所有 Promise 都成功时才 resolve。Promise.race
用于等待第一个完成的 Promise,无论它是成功还是失败。
这两个方法在处理并发任务时非常有用,尤其是在需要同时处理多个异步操作的情况下。