- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
考虑以下代码,其中包含 Bluebird 的 Promise.settle 的简化实现:
var a = Promise.reject('a');
var b = Promise.resolve('b');
var c = Promise.resolve('c');
var promises = [a,b,c];
function settled(promises) {
var alwaysFulfilled = promises.map(function (p) {
return p.then(
function onFulfilled(value) {
return { state: 'fulfilled', value: value };
},
function onRejected(reason) {
return { state: 'rejected', reason: reason };
}
);
});
return Promise.all(alwaysFulfilled);
}
//Update status message once all requests finish
settled(promises).then(function (outcomes) {
var count = 0;
outcomes.forEach(function (outcome) {
if (outcome.state == 'fulfilled') count++;
});
console.log(count + ' out of ' + outcomes.length + ' balances were updated');
});
这将记录“更新了 3 个余额中的 2 个”。为什么这与普通的 Promise.all 不同? alwaysFulfilled 不应该仍然包含一个被拒绝的 promise 作为它的第一个元素吗?
答案似乎在于我对 promises 的运作方式感到困惑。如果我在控制台中创建了一个被拒绝的 promise ,那么它就像这样:
var a = Promise.reject('a');
var b = a.then(function() {}, undefined);
var c = a.then(undefined, function() {});
a
Promise {[[PromiseStatus]]: "rejected", [[PromiseValue]]: "a"}
b
Promise {[[PromiseStatus]]: "rejected", [[PromiseValue]]: "a"}
c
Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: undefined}
为什么 c 被“解决”了?
最佳答案
理解您的问题的关键是,当您在 .then()
或 .catch()
中提供拒绝处理程序时,您是在告诉向系统保证您正在“处理”拒绝。因此,除非您的拒绝处理程序本身抛出或返回一个被拒绝的 promise ,否则该拒绝处理程序的返回值将进入一个已履行的 promise ,而不是一个被拒绝的 promise 。下面将对此进行更多解释......
其实反之亦然。如果您有拒绝处理程序并且基于拒绝的类型,您希望拒绝继续传播回被拒绝的 promise ,您必须从拒绝处理程序中抛出错误或返回被拒绝的 promise 。
This will log "2 out of 3 balances were updated". Why does this work differently than a plain Promise.all?
Promise.all()
在收到给定的 promise 列表中的第一个拒绝后立即返回一个被拒绝的 promise 。它不一定返回所有结果,如果您通过的任何 promise 被拒绝,它会返回拒绝。一旦一个 promise 被拒绝,它基本上就放弃了。这就是 Promise.settle()
的意义所在。它会为您提供所有结果,即使有些结果被拒绝,您也可以筛选所有结果。
Shouldn't alwaysFulfilled still contain a rejected promise as its first element?
如下所述,当您在 .then()
中有一个拒绝处理程序并且该拒绝处理程序不会抛出
或返回一个被拒绝的 promise (例如,它返回一个正常值,就像你正在做的那样),那么该 promise 拒绝被认为已处理,并且来自 .then()
处理程序的结果 promise 得到履行,而不是被拒绝。以下步骤中的更多解释...
The answer seems to lie in my confusion over how promises work. If I create a rejected promise in the console and .then it like so... Why is c "resolved"?
首先,.then()
返回一个新的 promise 。所以 a.then()
没有返回 a
。它返回一个新的 promise ,它是 .then()
处理程序中发生的事情的产物。
当你这样做时:
var c = Promise.reject('a').then(undefined, function() {});
这是正在发生的事情:
'a'
。.then()
链接到它,这会创建一个新的 promise 并将其返回到您的变量 c
中。.then()
的第二个处理程序。在调试或设计代码时,请记住这始终是异步调用的(这有时会使调试器中的人感到困惑)。undefined
。此时,Promise 系统认为拒绝“已处理”并且 .then()
的结果是具有 undefined
值的 fulfilled promise(这就是您的处理程序返回的内容) .如果您希望结果仍然被拒绝,那么您可以throw
或者您可以从拒绝处理程序中返回一个被拒绝的 promise 。以这种方式完成,因此您可以“处理”拒绝并保持 promise 链成功运行。此外,未处理的拒绝将导致被拒绝的 promise ,但拥有拒绝处理程序会告诉 promise 系统您的代码正在处理拒绝,并且将根据拒绝处理程序的返回结果形成最终的 promise 。
所以,所有这些都会导致 c
被拒绝:
// no reject handler
var c = a.then(function() {});
// throw from reject handler
var c = a.then(undefined, function() { throw new Error("whatever")});
// return rejected promise from reject handler
var c = a.then(undefined, function() { return Promise.reject("whatever")});
但是,如果你有一个拒绝处理程序并且它既不抛出
也不返回被拒绝的 promise ,那么拒绝被认为是“已处理”并且得到的 promise 将以你的处理程序的任何值解决返回。
关于javascript - Promise.settle 和 promise 履行与拒绝,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32160055/
我只想允许一个国家/地区访问,但排除该国家/地区内的代理。 这就是我所拥有的(为了方便起见,缩短了版本) order deny,allow deny from all allow from 139.
这个问题在这里已经有了答案: What is an unhandled promise rejection? (9 个回答) 关闭 4 年前。 我目前正在尝试实现我自己的 Promise,以便在 A
我在使用 Gitolite 推送 git 时遇到问题。 当我尝试这个时: git push origin :refs/tags/deployment 我收到这个错误: remote: D NAME/i
我已经为我的 laravel 5.0-dev 项目配置了 mysql,如下所示: 'mysql' => [ 'driver' => 'mysql', 'host' =>
我对 Web 和 SOF 进行了一些研究,但发现对于该错误没有任何真正的帮助。 我使用 Windows 10 Ubuntu Bash 安装了 Node 和 Puppeteer,但未能使其工作,但我设法
在我的应用审核期间,我收到了以下信息: “17.2:要求用户共享个人信息(例如电子邮件地址和生日)才能正常运行的应用将被拒绝 具体来说,您的应用仅使用Facebook登录名进行身份验证,但不包括该网站
我正在开发 VeriFone VX 终端的接口(interface)。虽然,这确实是一个普遍的 EMV 问题。我们的处理器的下限为零,因此它将始终在线发送。但是,如果它发生变化,您如何知道(哪些标签)
我编写了一些宏代码,根据表单提交向经理发送电子邮件(用于费用/审批流程),这是我使用谷歌表单/电子表格的第一个项目,所以也许我可能会错过一些简单的东西,但我为此浏览了 2 个教程,我的代码与重要的部分
clang 3.4 接受以下代码;而 vc++ NOV 2013 CTP 拒绝它并出现错误: error C2668: 'AreEqual' : ambiguous call to overloade
使用 nginx,您可以允许和拒绝范围和 ips (https://www.nginx.com/resources/admin-guide/restricting-access/)。使用realip模
官方编辑: 非常感谢您的帮助,但我仍然遇到问题。 我的 ffserver.conf 文件是这样的: # Port on which the server is listening. You must
我有一个问题:我是 Ubuntu 系统的根。我想授予用户(比如用户名是 X)执行任何命令的权限,但同时我有一个文件夹,除了我的用户(当然不是 X,因为它是 Admin ) 或根。有什么建议么?谢谢!
我使用 Apache2.2 作为 tomcat 服务器的前端。我想限制对某个位置的访问,但允许对子位置的所有访问,但遇到了一些麻烦。 我目前拥有的是: AllowOverride None
就像 this person ,我一直在为浏览器缓存 SSL session 而苦苦挣扎。简而言之,如果选择了客户端证书,则无法以编程方式清除状态,除非在 IE 中使用 document.execCo
我的网站是在由 Apache 服务器提供服务的 Angular 上设置的。我通过 View 将内容动态加载到主页上。 现在以下是我的问题: 我建立这个网站的主要目的是通过 google adsense
我最近遇到了我的应用程序的问题,当它突然被 Google Play 拒绝时因为他们发现我使用的是背景位置 .但实际上我并没有使用这个功能。我只有 ACCESS_COARSE_LOCATION和 ACC
function sendPushNotification(subscription, urlEncodedData){ try { webpush.sendNotification(su
我包裹了一个 request-promise-native调用返回 promise 的函数。 import request from 'request-promise-native'; functio
我正在开发我的 meteor 项目,并开始设置我的第一个更复杂的允许/拒绝规则。我发现很难看出哪些允许触发,哪些不允许触发,以及这些函数中的某些变量包含什么。例如: List.allow({ u
我正在 AngularJS 中创建一个 Factory,它是这样的: if (href) { return $http({ method: method, url: item.href });
我是一名优秀的程序员,十分优秀!