- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
这个问题在这里已经有了答案:
Wait until all promises complete even if some rejected
(20 个回答)
6年前关闭。
假设我有一个处理两个 promise 的 Promise.all()
。如果一个 promise 产生错误,但另一个 promise 解决了,我希望能够在 Promise.all()
解决后根据情况处理错误。
ES6 Promises 缺少解决方法,我假设是有充分理由的。但我不禁认为 .settle()
方法会让我更容易解决这个问题。
我是以错误的方式解决这个问题,还是用一种解决方法扩展 ES6 Promise 是正确的做法?
我如何考虑使用 .settle()
的一个例子:
Promise.all([Action1,Action2])
.settle(function(arrayOfSettledValues)
//if 1 failed but not 2, handle
//if 2 failed but not 1, handle
//etc....
)
最佳答案
Am I going about this the wrong way or is extending the ES6 Promises with a settle method the right thing to do here?
Promise.all()
生成
.settle()
类型行为,无论是否拒绝,都会为您提供所有结果,因为
Promise.all()
是“快速失败”,一旦第一个 promise 被拒绝,它就会返回,它只返回拒绝原因,没有其他结果。
.then()
任何操作的处理程序都会创建您的 promise 数组,以便它捕获任何拒绝并将它们转换为具有您可以测试的特定值的已履行 promise 。但是,这种类型的解决方案取决于实现,因为它完全取决于您返回的值类型,因此这并不完全是通用的。
.settle()
很有用。
Promise.all([...]).settle(...).then(...);
Promise.allSettled()
作为“类似定居”行为的标准实现。您可以在此答案的末尾看到更多信息。
Promise.all()
当你传递的第一个 promise 被拒绝时,它会拒绝并且它只返回那个拒绝。
.settle()
逻辑工作如下:
Promise.settle([...]).then(...);
Promise.settle()
实现。 :
// ES6 version of settle
Promise.settle = function(promises) {
function PromiseInspection(fulfilled, val) {
return {
isFulfilled: function() {
return fulfilled;
}, isRejected: function() {
return !fulfilled;
}, isPending: function() {
// PromiseInspection objects created here are never pending
return false;
}, value: function() {
if (!fulfilled) {
throw new Error("Can't call .value() on a promise that is not fulfilled");
}
return val;
}, reason: function() {
if (fulfilled) {
throw new Error("Can't call .reason() on a promise that is fulfilled");
}
return val;
}
};
}
return Promise.all(promises.map(function(p) {
// make sure any values are wrapped in a promise
return Promise.resolve(p).then(function(val) {
return new PromiseInspection(true, val);
}, function(err) {
return new PromiseInspection(false, err);
});
}));
}
Promise.settle()
将始终解析(从不拒绝),它使用
PromiseInspection
的数组解析允许您测试每个单独结果的对象,以查看它是解决还是拒绝,以及每个结果的值(value)或原因是什么。它通过附加
.then()
来工作传入的每个 Promise 的处理程序,处理来自该 Promise 的解析或拒绝,并将结果放入
PromiseInspection
对象然后成为 promise 的已解决值。
Promise.settle([...]).then(function(results) {
results.forEach(function(pi, index) {
if (pi.isFulfilled()) {
console.log("p[" + index + "] is fulfilled with value = ", pi.value());
} else {
console.log("p[" + index + "] is rejected with reasons = ", pi.reason());
}
});
});
.settle
我自己调用
.settleVal()
当您不需要实际的拒绝原因时,我经常发现它更容易使用,您只想知道给定的数组插槽是否被拒绝。在此版本中,您传入一个默认值,该值应替换任何被拒绝的 promise 。然后,您只得到一个返回值的平面数组,以及任何设置为默认值的被拒绝的值。例如,您通常可以选择
rejectVal
的
null
或
0
或
""
或
{}
它使结果更容易处理。这是功能:
// settle all promises. For rejected promises, return a specific rejectVal that is
// distinguishable from your successful return values (often null or 0 or "" or {})
Promise.settleVal = function(rejectVal, promises) {
return Promise.all(promises.map(function(p) {
// make sure any values or foreign promises are wrapped in a promise
return Promise.resolve(p).then(null, function(err) {
// instead of rejection, just return the rejectVal (often null or 0 or "" or {})
return rejectVal;
});
}));
};
Promise.settleVal(null, [...]).then(function(results) {
results.forEach(function(pi, index) {
if (pi !== null) {
console.log("p[" + index + "] is fulfilled with value = ", pi);
}
});
});
.settle()
的完全替代品因为有时您可能想知道它被拒绝的实际原因,或者您无法轻松区分被拒绝的值和未拒绝的值。但是,我发现超过 90% 的时间,这更容易使用。
.settle()
的最新简化留下
instanceof Error
在返回数组中作为区分解析值和拒绝错误的方法:
// settle all promises. For rejected promises, leave an Error object in the returned array
Promise.settleVal = function(promises) {
return Promise.all(promises.map(function(p) {
// make sure any values or foreign promises are wrapped in a promise
return Promise.resolve(p).catch(function(err) {
let returnVal = err;
// instead of rejection, leave the Error object in the array as the resolved value
// make sure the err is wrapped in an Error object if not already an Error object
if (!(err instanceof Error)) {
returnVal = new Error();
returnVal.data = err;
}
return returnVal;
});
}));
};
Promise.settleVal(null, [...]).then(function(results) {
results.forEach(function(item, index) {
if (item instanceof Error) {
console.log("p[" + index + "] rejected with error = ", item);
} else {
console.log("p[" + index + "] fulfilled with value = ", item);
}
});
});
.settle()
对于所有情况,只要
instanceof Error
从来都不是你的 promise 的解决值(value)(它真的不应该)。
.allSettled()
正在成为这种行为的标准。而且,这是一个 polyfill:
if (!Promise.allSettled) {
Promise.allSettled = function(promises) {
let wrappedPromises = Array.from(promises).map(p =>
this.resolve(p).then(
val => ({ state: 'fulfilled', value: val }),
err => ({ state: 'rejected', reason: err })
)
);
return this.all(wrappedPromises);
}
}
let promises = [...]; // some array of promises, some of which may reject
Promise.allSettled(promises).then(results => {
for (let r of results) {
if (r.state === 'fulfilled') {
console.log('fulfilled:', r.val);
} else {
console.log('rejected:', r.err);
}
}
});
Promise.allSettled()
本身总是解决,从不拒绝后续的
.then()
处理程序可以抛出或返回被拒绝的 promise 以使整个链拒绝。
关于javascript - ES6 Promise.all() 错误句柄 - 是否需要 .settle()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36605253/
我正在尝试用 C 语言编写一个使用 gstreamer 的 GTK+ 应用程序。 GTK+ 需要 gtk_main() 来执行。 gstreamer 需要 g_main_loop_run() 来执行。
我已经使用 apt-get 安装了 opencv。我得到了以下版本的opencv2,它工作正常: rover@rover_pi:/usr/lib/arm-linux-gnueabihf $ pytho
我有一个看起来像这样的 View 层次结构(基于其他答案和 Apple 的使用 UIScrollView 的高级 AutoLayout 指南): ScrollView 所需的2 个步骤是: 为 Scr
我尝试安装 udev。 udev 在 ./configure 期间给我一个错误 --exists: command not found configure: error: pkg-config and
我正在使用 SQLite 3。我有一个表,forums,有 150 行,还有一个表,posts,有大约 440 万行。每个帖子都属于一个论坛。 我想从每个论坛中选择最新帖子的时间戳。如果我使用 SEL
使用 go 和以下包: github.com/julienschmidt/httprouter github.com/shwoodard/jsonapi gopkg.in/mgo.v2/bson
The database仅包含 2 个表: 钱包(100 万行) 事务(1500 万行) CockroachDB 19.2.6 在 3 台 Ubuntu 机器上运行 每个 2vCPU 每个 8GB R
我很难理解为什么在下面的代码中直接调用 std::swap() 会导致编译错误,而使用 std::iter_swap 编译却没有任何错误. 来自 iter_swap() versus swap() -
我有一个非常简单的 SELECT *用 WHERE NOT EXISTS 查询条款。 SELECT * FROM "BMAN_TP3"."TT_SPLDR_55E63A28_59358" SELECT
我试图按部分组织我的 .css 文件,我需要从任何文件访问文件组中的任何类。在 Less 中,我可以毫无问题地创建一个包含所有文件导入的主文件,并且每个文件都导入主文件,但在 Sass 中,我收到一个
Microsoft.AspNet.SignalR.Redis 和 StackExchange.Redis.Extensions.Core 在同一个项目中使用。前者需要StackExchange.Red
这个问题在这里已经有了答案: Updating from Rails 4.0 to 4.1 gives sass-rails railties version conflicts (4 个答案) 关
我们有一些使用 Azure DevOps 发布管道部署到的现场服务器。我们已经使用这些发布管道几个月了,没有出现任何问题。今天,我们在下载该项目的工件时开始出现身份验证错误。 部署组中的节点显示在线,
Tip: instead of creating indexes here, run queries in your code – if you're missing any indexes, you
你能解释一下 Elm 下一个声明中的意思吗? (=>) = (,) 我在 Elm architecture tutorial 的例子中找到了它 最佳答案 这是中缀符号。实际上,这定义了一个函数 (=>
我需要一个 .NET 程序集查看器,它可以显示低级详细信息,例如元数据表内容等。 最佳答案 ildasm 是 IL 反汇编程序,具有低级托管元数据 token 信息。安装 Visual Studio
我有两个列表要在 Excel 中进行比较。这是一个很长的列表,我需要一个 excel 函数或 vba 代码来执行此操作。我已经没有想法了,因此转向你: **Old List** A
Closed. This question does not meet Stack Overflow guidelines。它当前不接受答案。 想要改善这个问题吗?更新问题,以便将其作为on-topi
我正在学习 xml 和 xml 处理。我无法很好地理解命名空间的存在。 我了解到命名空间帮助我们在 xml 中分离相同命名的元素。我们不能通过具有相同名称的属性来区分元素吗?为什么命名空间很重要或需要
我搜索了 Azure 文档、各种社区论坛和 google,但没有找到关于需要在公司防火墙上打开哪些端口以允许 Azure 所有组件(blob、sql、compute、bus、publish)的简洁声明
我是一名优秀的程序员,十分优秀!