javascript - 使用 Promise.allSettled 和 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);
哪些请求有效,哪些请求失败。我希望这很清楚。
解决方案
有趣的问题 - 问题是您实际上并没有模拟异步请求。实际上,您的两个请求方法只是创建同步/立即解决/拒绝的承诺。你需要把await
beforefailingRequest()
才能让被拒绝的承诺被捕获,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
正如预期的那样。
推荐阅读
- .net - curl 将文件上传到 .NET MultipartFileStreamProvider 时出错
- amazon-web-services - 激活 PossitiveSSL - 使用 AWS (ec2) 主机的 Namecheap
- python - 在 request.session 中获取 KeyError
- html - 我无法正确对齐我的 CSS 网格中的井字游戏项目,边框被弄乱了
- docker - Docker Swarm 路由网格连接超时
- javascript - 将 three.js 放在 HTML 中的另一个元素中
- javascript - 检查选择框选项是否重复超过特定时间
- html - 即使从 PC 访问时也显示网站的移动版本
- swift - 快速向 MapKit 注释视图添加操作
- github - MS 团队 github 连接器 - 可以移除身体吗?只想要消息中的标题