繁体   English   中英

如何处理这个 promise.all 案例?

[英]How to handle this promise.all case?

我们有一个并行的 promise 调用:- promise.all([p1,p2]).then().catch() 这里 p1,p2 是 2 个不同的 promise 调用。

  • p1 - 拒绝某些条件并显示 e1
  • p2 - 拒绝某些条件并显示 e2
  • p1 - 解决然后做某事
  • p2 - 不解决

p1,p2 拒绝条件不同。

如果 p1,p2 都拒绝,我们显示 e2

现在假设两者都拒绝,但 p1 首先拒绝,如何处理这个并显示 e2?

p1 的 p90 > p2 的 p90 但如果 p1 早于 p2 发生,则可能存在边缘情况,因此查询。

尝试使用 promise.allSettled 但它还有其他问题,即 p2 在 .then 块运行 2 次之后执行(结果中有 2 个 882601264401688 和相应的数组元素)。

我们尝试了多种方法,在 p1 失败的情况下使用特定的错误消息解决,但它不起作用。

(前言:Promise 术语可能令人困惑,大多数人使用不正确。 我关于术语的博文可能是一篇有用的读物。)

你看Promise.allSettled是对的。 如果你想在一个promise被满足而另一个被拒绝时做X,那就是go; 如果任何输入承诺被拒绝,您将获得一组结果,而不是Promise.all的短路行为。

p2 - 不解决

不清楚你的意思,但如果你的意思是如果p2在一定时间内没有解决(得到满足或拒绝)你需要做一些事情,你可能想使用Promise.race超时 promise。

没有代码很难帮助你,但这里有一个结合Promise.allSettledPromise.race的例子:

class TimeoutError extends Error {}

function timeout(ms) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            reject(new TimeoutError("timeout"));
        }, ms);
    });
}

async function test() {
    const p1 = // ...get the first promise...
    const p2 = // ...get the second promise...

    // Wait for the first to settle and the second to either settle or time out
    const [result1, result2] = await Promise.allSettled([
        p1,
        Promise.race([
            p2,
            timeout(150 /* or whatever, value in milliseconds */)
        ])
    ]);

    // See what happened
    if (result1.status === "fulfilled" && result2.status === "fulfilled") {
        // Both promises were fulfilled, see `result1.value` and `result2.value`
    } else if (result1.status === "fulfilled") {
        if (result2.reason instanceof TimeoutError) {
            // The first promise was fulfilled, the second timed out
        } else {
            // The first promise was fulfilled, the second was rejected
        }
    } else if (result2.status === "fulfilled") {
        // First promise was rejected, second was fulfilled
    } else {
        // Both promises were rejected, see `result1.reason` and `result2.reason`
    }
}

现场示例:

 function f1(ms, fulfill) { return new Promise((resolve, reject) => { setTimeout(() => { if (fulfill) { resolve("1 - OK"); } else { reject(new Error("1 - failed")); } }, ms); }); } function f2(ms, fulfill) { return new Promise((resolve, reject) => { setTimeout(() => { if (fulfill) { resolve("2 - OK"); } else { reject(new Error("2 - failed")); } }, ms); }); } class TimeoutError extends Error {} function timeout(ms) { return new Promise((resolve, reject) => { setTimeout(() => { reject(new TimeoutError("timeout")); }, ms); }); } async function example(ms1, fulfill1, ms2, fulfill2, msTimeout) { const p1 = f1(ms1, fulfill1); const p2 = f2(ms2, fulfill2); // Wait for the first to settle and the second to either settle or time out const [result1, result2] = await Promise.allSettled([ p1, Promise.race([p2, timeout(msTimeout)]) ]); // See what happened if (result1.status === "fulfilled" && result2.status === "fulfilled") { console.log(`Both promises were fulfilled:`); console.log(`result1.value = ${result1.value}`); console.log(`result2.value = ${result2.value}`); } else if (result1.status === "fulfilled") { if (result2.reason instanceof TimeoutError) { console.log(`The first promise was fulfilled, the second timed out`); console.log(`result1.value = ${result1.value}`); console.log(`result2 was a timeout`); } else { console.log(`The first promise was fulfilled, the second was rejected`); console.log(`result1.value = ${result1.value}`); console.log(`result2.reason = ${result2.reason}`); } } else if (result2.status === "fulfilled") { console.log(`The first promise was rejected, second was fulfilled`); console.log(`result1.reason = ${result1.reason}`); console.log(`result2.value = ${result2.value}`); } else { // Both promises were rejected, see `result1.reason` and `result2.reason` console.log(`The first promise was rejected, second was fulfilled`); console.log(`result1.reason = ${result1.reason}`); console.log(`result2.rason = ${result2.reason}`); } } function test(label, ms1, fulfill1, ms2, fulfill2, msTimeout) { console.log(`${label}:`); example(ms1, fulfill1, ms2, fulfill2, msTimeout).catch((error) => { console.error(`Unexpected error in test: ${error.stack?? String(error)}`); }); } const onClick = (id, fn) => document.getElementById(id).addEventListener("click", fn); onClick("both-fulfill", () => test("Both Fulfill", 100, true, 150, true, 200)); onClick("first-fulfills", () => test("First Fulfills", 100, true, 150, false, 200)); onClick("second-times-out", () => test("Second Times Out", 100, true, 250, true, 200)); onClick("second-fulfills", () => test("Second Fulfills", 100, false, 150, true, 200)); onClick("both-reject", () => test("Both Reject", 100, false, 150, false, 200));
 <input type="button" id="both-fulfill" value="Both Fulfill"> <input type="button" id="first-fulfills" value="First Fulfills"> <input type="button" id="second-times-out" value="Second Times Out"> <input type="button" id="second-fulfills" value="Second Fulfills"> <input type="button" id="both-reject" value="Both Reject">

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM