gpt4 book ai didi

node.js - 在 try/catch block 中等待两个 promise 导致 "Unhandled promise rejection"

转载 作者:行者123 更新时间:2023-12-03 12:13:37 25 4
gpt4 key购买 nike

这个问题在这里已经有了答案:





Waiting for more than one concurrent await operation

(4 个回答)


去年关闭。




我想等待两个并行运行的 promise 。我不想连续等待每个 promise (有效但速度较慢)。

出于这个原因,我认为我可以先创建两个 promise 来让它们滚动,比如两个网络请求,然后等待它们并能够在 catch 块中捕获错误。该假设似乎不正确,因为我在运行此示例代码时收到警告。

  • 这是为什么?
  • 我如何最好地并行运行两个或多个网络请求,否则使用优雅的代码?
  • 为什么 Typescript 没有警告我 catch-block 不会
    捕获拒绝?
  • async function testMultipleAwait() {
    try {
    const aPromise = new Promise((resolve) => {
    setTimeout(() => resolve('a'), 200);
    });

    const bPromise = new Promise((_, reject) => {
    setTimeout(() => reject('b'), 100);
    });

    const a = await aPromise;
    const b = await bPromise;
    } catch (e) {
    console.log('Caught error', e);
    }
    }

    testMultipleAwait();

    不会导致“捕获错误”输出,而是我得到
    tsc test-try-catch-await.ts && node test-try-catch-await.js

    (node:31755) UnhandledPromiseRejectionWarning: b
    (node:31755) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
    (node:31755) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
    Caught error b
    (node:31755) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 1)

    最佳答案

    我想我知道问题是什么。即使 promise 以并发方式开始,您仍在等待 aPromisebPromise依次:

    const a = await aPromise; // First await this...
    const b = await bPromise; // and then start to await this

    This is not so much of a problem when both promises fulfill. It would keep jou waiting about as much time as Promise.all would, and then happily continue. That is why this problem is not so obvious at all...


    重要的是要知道,由于 async/await,这个 try-catch 在后台被转换为 promise。这意味着首先等待的语句之后的任何内容都将在 promise.then 回调函数中结束。
    所以, const b = await bPromise之前不会运行 const a已到达(200 毫秒后)。 bPromise提前 100 毫秒失败。
    这并不是说 async/await 不会发现错误或附加您的 catch完全阻止(如 promise.catch(...))。毕竟, Node 警告和捕获处理程序都有终端输出:
    tsc test-try-catch-await.ts && node test-try-catch-await.js

    1 first node sees the error > (node:31755) UnhandledPromiseRejectionWarning: b
    2 (node:31755) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
    3 (node:31755) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
    4 and then your catch handler > Caught error b
    5 (node:31755) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 1)
    所以 de catch 子句确实有效,但是 async 函数不会费心将它附加到 bPromise直到至少 200 毫秒之后。第 5 行似乎证实了这一点:
    PromiseRejectionHandledWarning: Promise rejection was handled asynchronously.

    Rejection errors get thrown as soon as the microtask queue is empty.


    promise 拒绝已处理,但 Node 认为您为时已晚。您可以使用 Promise.all 解决此问题。 .这样你 await一次,您的异步函数将首先捕获每个潜在错误。
    // Everything just as it is.. and then:

    const [a, b] = await Promise.all([
    aPromise,
    bPromise,
    ]);

    因为我很好奇,所以我在 chrome 控制台中输入了你的代码,看看会发生什么。错误日志会在很短的时间内弹出(我猜是 100 毫秒)。查看此输出,您只能听到 chrome 说:

    "Ah wait! It is being caught after all. Here's the message!"


    Click for gif animation.
    chrome output after running the code

    关于node.js - 在 try/catch block 中等待两个 promise 导致 "Unhandled promise rejection",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61615834/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com