使用 Promise.allSettled 和 try/catch 拒绝未处理的承诺

时间:2021-05-12 11:13:38

标签: javascript node.js promise try-catch

我的想法如下: 我想同时发送多个请求,而不必等到先前执行。

所以我的伪代码如下:

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

function failingRequest(){
    return new Promise((resolve, reject) => {
        reject('Request failed');
    });
}

function successRequest(){
    return new Promise((resolve, reject) => {
        resolve('Request success');
    });
}

async function main() {
    try {
        let executions = [];
        executions.push(failingRequest());
        await sleep(4000);
        executions.push(successRequest());
        let result = await Promise.allSettled(executions);
        console.log(result);
    } catch (err) {
        console.log('Outer error occured.');
        console.log(err.message);
    }

    console.log('done');
}
main();

在此处运行此代码可在浏览器中按预期工作,但会为我提供以下与节点一起运行的输出:

node:761) UnhandledPromiseRejectionWarning: Request failed
api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:761) [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 exi not handled will terminate the Node.js process with a non-zero exit code.
[
  { status: 'rejected', reason: 'Request failed' },
  { status: 'fulfilled', value: 'Request success' }
]
done
(node:761) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 1)

知道为什么会这样吗?

请注意,我只插入了 sleep,所以我可以测试 catch 块是否会在第一个请求失败的情况下被执行这不是我们想要的行为。我想同时发起这些请求,我不在乎一个是否失败。我想稍后与 let result = await Promise.allSettled(executions); 检查哪些请求有效,哪些失败。我希望这很清楚。

2 个答案:

答案 0 :(得分:1)

有趣的问题 - 问题是您实际上并没有模拟异步请求。事实上,您的两个请求方法只是创建同步/立即解决/拒绝的承诺。您需要将 await 放在 failingRequest() 之前,以便在周围的 try/catch 中捕获被拒绝的承诺,但这可能不是您想要的。

相反,您不应该立即“开始”承诺,而应该是这样的:

try {
        let executions = [];
        executions.push(failingRequest);
        await sleep(4000);
        executions.push(successRequest);
        let result = await Promise.allSettled(executions.map(promiseFn => promiseFn()));
        console.log(result);
    } catch (err) {
        console.log('Outer error occured.');
        console.log(err.message);
    }

这将记录

[
  { status: 'rejected', reason: 'Request failed' },
  { status: 'fulfilled', value: 'Request success' }
]
done

正如预期的那样。

答案 1 :(得分:0)

<块引用>

知道为什么会这样吗?

您创建 failingRequest(),然后等待 4 秒再处理它。

<块引用>

我只插入了 sleep 以便我可以测试

...因此你造成了未经处理的拒绝。删除 await sleep(4000);,它会按预期工作!

相关问题