- 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/
尝试使用集成到 QTCreator 的表单编辑器,但即使我将插件放入 QtCreator.app/Contents/MacOS/designer 也不会显示。不过,相同的 dylib 文件确实适用于独
在此代码示例中。 “this.method2();”之后会读到什么?在返回returnedValue之前会跳转到method2()吗? public int method1(int returnedV
我的项目有通过gradle配置的依赖项。我想添加以下依赖项: compile group: 'org.restlet.jse', name: 'org.restlet.ext.apispark', v
我将把我们基于 Windows 的客户管理软件移植到基于 Web 的软件。我发现 polymer 可能是一种选择。 但是,对于我们的使用,我们找不到 polymer 组件具有表格 View 、下拉菜单
我的项目文件夹 Project 中有一个文件夹,比如 ED 文件夹,当我在 Eclipse 中指定在哪里查找我写入的文件时 File file = new File("ED/text.txt"); e
这是奇怪的事情,这个有效: $('#box').css({"backgroundPosition": "0px 250px"}); 但这不起作用,它只是不改变位置: $('#box').animate
这个问题在这里已经有了答案: Why does OR 0 round numbers in Javascript? (3 个答案) 关闭 5 年前。 Mozilla JavaScript Guide
这个问题在这里已经有了答案: Is the function strcmpi in the C standard libary of ISO? (3 个答案) 关闭 8 年前。 我有一个问题,为什么
我目前使用的是共享主机方案,我不确定它使用的是哪个版本的 MySQL,但它似乎不支持 DATETIMEOFFSET 类型。 是否存在支持 DATETIMEOFFSET 的 MySQL 版本?或者有计划
研究 Seam 3,我发现 Seam Solder 允许将 @Named 注释应用于包 - 在这种情况下,该包中的所有 bean 都将自动命名,就好像它们符合条件一样@Named 他们自己。我没有看到
我知道 .append 偶尔会增加数组的容量并形成数组的新副本,但 .removeLast 会逆转这种情况并减少容量通过复制到一个新的更小的数组来改变数组? 最佳答案 否(或者至少如果是,则它是一个错
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
noexcept 函数说明符是否旨在 boost 性能,因为生成的对象中可能没有记录异常的代码,因此应尽可能将其添加到函数声明和定义中?我首先想到了可调用对象的包装器,其中 noexcept 可能会产
我正在使用 Angularjs 1.3.7,刚刚发现 Promise.all 在成功响应后不会更新 angularjs View ,而 $q.all 会。由于 Promises 包含在 native
我最近发现了这段JavaScript代码: Math.random() * 0x1000000 10.12345 10.12345 >> 0 10 > 10.12345 >>> 0 10 我使用
我正在编写一个玩具(物理)矢量库,并且遇到了 GHC 坚持认为函数应该具有 Integer 的问题。是他们的类型。我希望向量乘以向量以及标量(仅使用 * ),虽然这可以通过仅使用 Vector 来实现
PHP 的 mail() 函数发送邮件正常,但 Swiftmailer 的 Swift_MailTransport 不起作用! 这有效: mail('user@example.com', 'test
我尝试通过 php 脚本转储我的数据,但没有命令行。所以我用 this script 创建了我的 .sql 文件然后我尝试使用我的脚本: $link = mysql_connect($host, $u
使用 python 2.6.4 中的 sqlite3 标准库,以下查询在 sqlite3 命令行上运行良好: select segmentid, node_t, start, number,title
我最近发现了这段JavaScript代码: Math.random() * 0x1000000 10.12345 10.12345 >> 0 10 > 10.12345 >>> 0 10 我使用
我是一名优秀的程序员,十分优秀!