总结
此代码表示执行一系列 Promise 并按照解析顺序返回其“解析值”的功能。它还包括一个限制器,用于限制可以从给定的 Promise 数组中解析的 Promise 的数量。
限制如果限制器超过了 Promise 数组的长度,则抛出拒绝。 如果任何 Promise 抛出错误,则抛出拒绝。 如果已解决的 Promise 数量达到限制值,则按其解决顺序返回已解决的 Promise,并忽略其余的 Promise。
问题我有两个不同版本的代码:
v1 - 实现 then-catch 链来执行功能。 v2 - 实现 then ,并将解析和拒绝回调作为两个参数。 在 v1 的情况下,即使此承诺列表中的承诺被拒绝,承诺也不会引发拒绝。
但是,在 v2 的情况下,代码按预期工作,即,当任何 Promise 拒绝时,它会抛出拒绝。
代码v1
async function somePromises(promises, promisesToWait) {
// Throws error if promises to wait for is greater than promises in the `promise` array
if (promisesToWait > promises.length) {
return Promise.reject("Count is greater than the number of promises");
}
return await new Promise((resolve, reject) => {
const resolvedPromiseValues = []; // stores the values of resolved values
let hasRejected = false; // tracks the rejection
promises.forEach((promise) => {
promise()
.then((resolvedValue) => {
// Does not execute if rejected. SOMEHOW, NOT WORKING in v1
if (hasRejected) return;
if (resolvedPromiseValues.length < promisesToWait) {
resolvedPromiseValues.push(resolvedValue);
if (resolvedPromiseValues.length === promisesToWait) {
resolve(resolvedPromiseValues);
}
}
})
.catch((error) => {
if (!hasRejected) {
hasRejected = true;
}
reject(error);
});
});
});
}
const rejectablePromises = [
() => Promise.resolve(1),
() => Promise.resolve(2),
() => Promise.reject("I will reject"),
() => Promise.resolve(3),
];
async function main() {
somePromises(rejectablePromises, 3).then(console.log).catch(console.error);
}
main();
// Expected output: I will reject
// Actual output: [1, 2, 3]
async function somePromises(promises, promisesToWait) {
// Throws error if promises to wait for is greater than promises in the `promise` array
if (promisesToWait > promises.length) {
return Promise.reject("Count is greater than the number of promises");
}
return await new Promise((resolve, reject) => {
const resolvedPromiseValues = []; // stores the values of resolved values
let hasRejected = false; // tracks the rejection
promises.forEach((promise) => {
promise().then(
(resolvedValue) => {
// Should not execute if rejected. WORKS AS EXPECTED in v2
if (hasRejected) return;
if (resolvedPromiseValues.length < promisesToWait) {
resolvedPromiseValues.push(resolvedValue);
if (resolvedPromiseValues.length === promisesToWait)
resolve(resolvedPromiseValues);
}
},
(error) => {
if (!hasRejected) {
hasRejected = true;
}
reject(error);
}
);
});
});
}
const rejectablePromises = [
() => Promise.resolve(1),
() => Promise.resolve(2),
() => Promise.reject("I will reject"),
() => Promise.resolve(3),
];
async function main() {
somePromises(rejectablePromises, 3).then(console.log).catch(console.error);
}
main();
// Expected output: I will reject
// Actual output: I will reject
这两个实现承诺有区别吗?我阅读了文档,但找不到两者之间的任何清晰度。问 ChatGPT,它说这只是可读性问题。
我错过了什么?
.then(a).catch(b)
a
执行过程中抛出的错误,而 .then(a, b)
则不会:
Promise.resolve(1)
.then(() => { throw "bad" })
.catch((err) => console.log("caught in .catch()"));
Promise.resolve(1)
.then(() => { throw "bad" }, (err) => console.log("caught in .then()"));
.then(a).catch(b)
then()
,另一个来自 .catch()
:
queueMicrotask(() => {
console.log("microtask 1");
queueMicrotask(() => {
console.log("microtask 2");
queueMicrotask(() => {
console.log("microtask 3");
});
});
});
Promise.reject("bad")
.then(() => { })
.catch((err) => console.log("caught in .catch()"));
Promise.reject("bad")
.then(() => { }, (err) => console.log("caught in .then()"));
虽然您可能要记住第一个区别,但您的问题是由第二个区别引起的。由于您的所有 Promise 都已解决,因此在使用
.then().catch()
时,您将仅选择已解决的 Promise,并将拒绝的 Promise 移至列表末尾,并在示例中实际忽略它。