- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我无法理解为什么拒绝没有通过 promise 链传递,我希望有人能够帮助我理解原因。对我来说,将功能附加到一系列 promise 意味着我依赖于最初的 promise 来实现的意图。这很难解释,所以让我先展示一个我的问题的代码示例。 (注意:这个例子是使用 Node 和延迟 Node 模块。我用 Dojo 1.8.3 测试过,结果是一样的)
var d = require("deferred");
var d1 = d();
var promise1 = d1.promise.then(
function(wins) { console.log('promise1 resolved'); return wins;},
function(err) { console.log('promise1 rejected'); return err;});
var promise2 = promise1.then(
function(wins) { console.log('promise2 resolved'); return wins;},
function(err) { console.log('promise2 rejected'); return err;});
var promise3 = promise2.then(
function(wins) { console.log('promise3 resolved'); return wins;},
function(err) { console.log('promise3 rejected'); return err;});
d1.reject(new Error());
运行这个操作的结果是这样的输出:
promise1 rejected
promise2 resolved
promise3 resolved
好吧,对我来说,这个结果没有意义。通过附加到这个 Promise 链上,每一个都暗示着它将依赖于 d1 的成功解决和传递到链上的结果。如果promise1 中的promise 没有收到wins 值,而是在它的错误处理程序中得到了一个err 值,那么链中的下一个promise 怎么可能调用它的success 函数呢?它无法将有意义的值传递给下一个 Promise,因为它本身没有获得值。
我可以用另一种方式来描述我的想法:共有三个人,John、Ginger 和 Bob。约翰拥有一家小部件商店。 Ginger 走进他的商店,要了一袋颜色各异的小玩意儿。他没有库存,所以他向他的分销商发送请求,要求将它们运送给他。与此同时,他给了 Ginger 一张雨票,说明他欠她一袋小工具。 Bob 发现 Ginger 正在获取小部件,并请求在她完成这些小部件后让他获取蓝色小部件。她同意并给了他一张纸条,说明她会的。现在,John 的分销商在他们的供应中找不到任何小部件,并且制造商不再生产它们,所以他们通知 John,John 又通知 Ginger 她无法获得这些小部件。 Bob 自己没有得到一个蓝色的小部件,怎么能从 Ginger 那里得到呢?
我对这个问题的第三个更现实的观点是。假设我有两个要更新到数据库的值。一个依赖于另一个的 id,但是在我已经将其插入数据库并获得结果之前,我无法获取该 id。最重要的是,第一个插入依赖于来自数据库的查询。数据库调用返回我用来将两个调用链接成一个序列的 promise 。
var promise = db.query({parent_id: value});
promise.then(function(query_result) {
var first_value = {
parent_id: query_result[0].parent_id
}
var promise = db.put(first_value);
promise.then(function(first_value_result) {
var second_value = {
reference_to_first_value_id: first_value_result.id
}
var promise = db.put(second_value);
promise.then(function(second_value_result) {
values_successfully_entered();
}, function(err) { return err });
}, function(err) { return err });
}, function(err) { return err });
现在,在这种情况下,如果 db.query 失败,它将调用第一个 then 的 err 函数。但随后它会调用下一个 promise 的成功函数。虽然该 promise 期待第一个值的结果,但它会从其错误处理函数中获取错误消息。
所以,我的问题是,如果我必须在我的成功函数中测试错误,为什么我会有一个错误处理函数?
抱歉,这篇文章太长了。我只是不知道如何用另一种方式解释它。
更新和更正
(注意:我删除了我曾经对某些评论做出的回复。因此,如果有人对我的回复发表评论,他们的评论可能会因为我删除它而显得断章取义。抱歉,我试图将其保留为尽可能短。)
感谢所有回复的人。我想首先向大家道歉,因为我的问题写得太差了,尤其是我的伪代码。我试图保持简短有点过于激进。
感谢 Bergi 的回复,我想我发现了我的逻辑错误。我想我可能忽略了另一个导致我遇到的问题的问题。这可能导致 promise 链的工作方式与我想象的不同。我仍在测试我的代码的不同元素,所以我什至不能形成一个正确的问题来看看我做错了什么。不过,我确实想更新你们所有人,并感谢你们的帮助。
最佳答案
To me, this result doesn't make sense. By attaching to this promise chain, each then is implying the intent that it will be dependant upon the successful resolution of d1 and a result being passed down the chain
没有。您所描述的不是链,而是将所有回调附加到 d1
。然而,如果你想用 then
链接某些东西,promise2
的结果取决于 promise1
的分辨率以及 然后
回调处理它。
文档状态:
Returns a new promise for the result of the callback(s).
.then
方法通常被视为 Promises/A specification (或更严格的 Promsises/A+ one )。这意味着回调 shell 返回的 Promise 将被同化为 promise2
的解析,如果没有成功/错误处理程序,则相应的结果将直接传递给 promise2
- 所以你可以简单地省略处理程序来传播错误。
然而,如果错误已处理,则生成的 promise2
被视为已修复,并将使用该值实现。如果您不想这样,您将不得不重新throw
错误,就像在 try-catch 子句中一样。或者,您可以从处理程序返回一个(待)拒绝的 promise 。不知道 Dojo 的拒绝方式是什么,但是:
var d1 = d();
var promise1 = d1.promise.then(
function(wins) { console.log('promise1 resolved'); return wins;},
function(err) { console.log('promise1 rejected'); throw err;});
var promise2 = promise1.then(
function(wins) { console.log('promise2 resolved'); return wins;},
function(err) { console.log('promise2 rejected'); throw err;});
var promise3 = promise2.then(
function(wins) { console.log('promise3 resolved'); return wins;},
function(err) { console.log('promise3 rejected'); throw err;});
d1.reject(new Error());
How is Bob able to get a blue widget from Ginger when didn't get any herself?
他应该做不到。如果没有错误处理程序,他只会感知到消息(((来自 John)来自 John)来自 Ginger)没有留下任何小部件。然而,如果 Ginger 为这种情况设置了一个错误处理程序,如果 John 或他的分销商没有蓝色小部件,她仍然可以履行她的 promise ,即给 Bob 一个小部件,给他一个来自她自己小屋的绿色小部件。
要将您的错误回调转换为元数据,来自处理程序的 return err
就像说“如果没有留下任何小部件,只需给他一个没有留下任何小部件的注释 - 它是和所需的小部件一样好”。
In the database situation, if the db.query failed, it would call the err function of the first then
...这意味着错误已在此处处理。如果你不这样做,只需省略错误回调。顺便说一句,您的成功回调不会 return
他们正在创建的 promise ,因此它们似乎毫无用处。正确的是:
var promise = db.query({parent_id: value});
promise.then(function(query_result) {
var first_value = {
parent_id: query_result[0].parent_id
}
var promise = db.put(first_value);
return promise.then(function(first_value_result) {
var second_value = {
reference_to_first_value_id: first_value_result.id
}
var promise = db.put(second_value);
return promise.then(function(second_value_result) {
return values_successfully_entered();
});
});
});
或者,因为您不需要闭包来访问先前回调的结果值,甚至:
db.query({parent_id: value}).then(function(query_result) {
return db.put({
parent_id: query_result[0].parent_id
});
}).then(function(first_value_result) {
return db.put({
reference_to_first_value_id: first_value_result.id
});
}.then(values_successfully_entered);
关于javascript - 链式 promise 不会在拒绝时传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16371129/
我只想允许一个国家/地区访问,但排除该国家/地区内的代理。 这就是我所拥有的(为了方便起见,缩短了版本) 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 });
我是一名优秀的程序员,十分优秀!