javascript - JS Promises.all() - 如何防止“捕获”停止承诺链?
问题描述
给定一组 Promise 和 Promise.all() 语句,如果其中一个 Promise 失败,则整个链停止(它不等待任何后续 Promise 完成)并且 Promise.all().catch() 触发,但 Promise.all().then() 没有。
但是,如果各个 Promise 有自己的“catch”块,并且如果任何导致 Promise 失败的问题都可以在该 catch 块中修复,那么我们如何防止其余的 Promise 被忽略/失败,这样 Promise. all().then() 还会执行吗?有没有办法从 .catch() 块中“否定”错误,所以 Promises.all() 看不到它?我return Promise.resolve()
在 .catch() 块的末尾尝试过,但它不起作用。
例子:
let promise_array = [];
let p = somePromisyFunction1()
.then(() => { // Do something good })
.catch(() => { // Handle the bad });
promise_array.push(p);
p = somePromisyFunction2()
.then(() => { // Do something good })
.catch(() => { // Handle the bad });
promise_array.push(p);
p = somePromisyFunction3()
.then(() => { // Do something good })
.catch(() => { // Handle the bad });
promise_array.push(p);
// ...
// More Promisy functions added to promise_array here...
// ...
Promise.all(promise_array)
.then(() => { // We're all done! All promises fulfilled. })
.catch(() => { // Something went wrong! });
在此示例中,如果 somePromisyFunctionX() 中的任何一个失败,则该函数的 .catch() 子句将执行,然后 Promise.all.catch() 子句也将立即执行,而无需等待任何后续的 Promise 完成.
但是,如果我们可以修复发生的任何坏事,在单个函数的 .catch() 子句中,我们如何防止 Promises.all().catch() 立即被触发,而是允许其余的 Promise 可以执行提前并实现?在某种程度上,在 .catch() 子句中,我们可以“否定”错误,因此看起来承诺实际上成功实现而不是看起来失败?
我可以使用 try/catch 块在 async/await 函数中执行此操作,但不确定如何使用 .then/.catch 执行此操作。
解决方案
是的,您需要做的就是return
从失败的承诺中捕获一些东西,它将作为解决方案“恢复”Promise.all
希望这能证明。没有整个链catch
中somePromisyFunction2
的 将失败(通过注释掉它来检查),但有了它,整个链就会成功并恢复值
let promise_array = [];
let p = somePromisyFunction1()
//.then(() => { // Do something good })
// .catch(() => { // Handle the bad });
promise_array.push(p);
p = somePromisyFunction2()
//.then(() => { // Do something good })
.catch((v) => "2 - " + v);
promise_array.push(p);
p = somePromisyFunction3()
//.then(() => { // Do something good })
//.catch(() => { // Handle the bad });
promise_array.push(p);
// ...
// More Promisy functions added to promise_array here...
// ...
Promise.all(promise_array)
.then((v) => { console.log("all good",v) })
.catch(() => { console.log("something bad") });
function somePromisyFunction1(){
return new Promise(resolve => resolve("1"));
}
function somePromisyFunction2(){
return new Promise((resolve,reject) => reject("oh no something went wrong!"));
}
function somePromisyFunction3(){
return new Promise(resolve => resolve("3"));
}
您也可以选择使用allSettled
而不是,all
然后您可以内联处理故障
let promise_array = [];
let p = somePromisyFunction1()
//.then(() => { // Do something good })
// .catch(() => { // Handle the bad });
promise_array.push(p);
p = somePromisyFunction2()
//.then(() => { // Do something good })
//.catch((v) => "2 - " + v);
promise_array.push(p);
p = somePromisyFunction3()
//.then(() => { // Do something good })
//.catch(() => { // Handle the bad });
promise_array.push(p);
// ...
// More Promisy functions added to promise_array here...
// ...
Promise.allSettled(promise_array)
.then((v) => { console.log("all good",v) })
.catch(() => { console.log("something bad") });
function somePromisyFunction1(){
return new Promise(resolve => resolve("1"));
}
function somePromisyFunction2(){
return new Promise((resolve,reject) => reject("oh no something went wrong!"));
}
function somePromisyFunction3(){
return new Promise(resolve => resolve("3"));
}
推荐阅读
- mongodb - 如何在我试图查找包含查询中所有标签的文档时发出猫鼬查找请求
- api - 使用 API 网关保护云功能
- java - 如何在交换机中创建新对象
- zip - 使用 Pigz 问题压缩目录
- php - 在 Woocommerce 中带有商店下拉列表的自定义取货运输方式
- magento2 - Magento2 到 Magento2 数据迁移
- batch-file - 从批处理文件中自动提供使用 Plink 执行的“su”的 root 用户密码
- javascript - 图片位置不改变CSS
- javascript - 解析具有多个标题行的 CSV
- ios - 为“任何 iOS 设备”构建 Swift 包时找不到 SwiftUI 或组合类型