javascript 如何将额外的数据向下传递到 Parse Promise 链
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25254355/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to pass extra data down a Parse Promise chain
提问by Joris Mans
In my Parse Cloude code I need to run a few successive queries, each of them using a "find()".
在我的 Parse Cloude 代码中,我需要运行几个连续的查询,每个查询都使用“find()”。
Example:
例子:
var promise = firstQuery.get(objectId).then(function(result1){
return secondQuery.find();
}).then(function(result2){
return thirdQuery.find();
}).then(function(result3) {
// here I want to use "result1", "result2" and "result3"
});
The question is: how do I access "result1" and "result2" in the final "then" statement, without assigning them to variables declared in the parent scope.
问题是:如何在最终的“then”语句中访问“result1”和“result2”,而不将它们分配给在父作用域中声明的变量。
Why do I ask this: You cannot use the parent scope trick if you are nesting a bunch of promises which you create in a loop in order for them to be executed in parallel (imagine a for loop around the above statement whereby all the promises are put in an array and then evaluated using "Parse.Promise.when". They would all start modifying the parent scope variables at the same time.)
我为什么要问这个问题:如果您嵌套一堆在循环中创建的 Promise 以便它们并行执行,则不能使用父作用域技巧(想象一下围绕上述语句的 for 循环,其中所有的 Promise 都是放入一个数组,然后使用“Parse.Promise.when”进行评估。它们将同时开始修改父作用域变量。)
Can I create some kind of promise object where I could return something along the lines of:
我可以创建某种承诺对象,在那里我可以返回以下内容:
Parse.promise({result:result1,findResult:secondQuery.find()};
so I could get the values out of the "result2" parameter by doing
所以我可以通过执行从“result2”参数中获取值
result2.result
and
和
result2.findResult
I hope I make myself clear. This is not very easy to explain.
我希望我说清楚。这不是很容易解释。
回答by Retsam
You can make use of closuresto do this, without the need for any extra objects or wrapping.
您可以使用闭包来做到这一点,而无需任何额外的对象或包装。
var promise = firstQuery.get(objectId).then(function(result1){
return secondQuery.find()
.then(function(result2) {
return thirdQuery.find()
.then(function(result3) {
//can use result1, result2, result3 here
});
});
});
This "nested" syntax is identical in function to your "chaining" syntax.
这种“嵌套”语法在功能上与“链接”语法相同。
EDIT based on comments
根据评论编辑
If your promise chain is long and complex enough that this nested syntax becomes ungainly, the logic is probably complex enough to merit abstraction into its own function.
如果您的 Promise 链足够长且足够复杂,以至于这种嵌套语法变得笨拙,那么逻辑可能足够复杂,值得将其抽象为自己的函数。
function complexQuery(objectId) {
var results = {};
return firstQuery.get(objectId).then(function(result1) {
results.result1 = result1;
return secondQuery.find();
})
.then(function(result2) {
results.result2 = result2;
return thirdQuery.find();
})
.then(function(result3) {
results.result3 = result3;
return results;
});
}
complexQuery(objectId)
.then(function (results) {
//can use results.result1, results.result2, results.result3
});
Personally, I think that's easier to read and maintain than messing around with .bind
.
就个人而言,我认为这比使用.bind
.
回答by Benjamin Gruenbaum
You cannot use the parent scope trick
您不能使用父作用域技巧
Well, since both the other answers do this, let me suggest a solution that doesn't. You can pass resolved promises along. This also has the added benefit of no nesting or closures.
好吧,由于其他两个答案都这样做,让我提出一个没有的解决方案。您可以传递已解决的承诺。这还具有无嵌套或闭包的额外好处。
This is based on the concept that promises are proxies for values already, so you don't actually haveto create one long chain:
这是基于承诺已经是值的代理的概念,因此您实际上不必创建一个长链:
var firstObject = firstQuery.get(objectId);
var secondObject = firstObject.then(secondQuery.find.bind(secondQuery));
var thirdObject = secondObject.then(thirdQuery.find.bind(thirdQuery));
Promise.all(firstObject, secondObject, thirdObject).then(function(r1, r2, r3){
// here you can use "r1", "r2" and "r3"
});
In standard promises, rather than parse code this would look similar:
在标准 Promise 中,这看起来类似,而不是解析代码:
Promise.all([firstObject, secondObject, thirdObject]).then(function(){
var r1 = arguments[0], r2 = arguments[1], r3 = arguments[2];
// here you can use "r1", "r2" and "r3"
});
With bluebird you can use .spread
for a shortcut or .bind
or actual context. If you absolutely must create one chain, you can pass context by returning multiple promises using Promise.all but I believe this approach is preferable.
使用 bluebird,您可以将其.spread
用于快捷方式.bind
或实际上下文。如果您绝对必须创建一个链,您可以通过使用 Promise.all 返回多个承诺来传递上下文,但我相信这种方法更可取。
回答by Timothy Walters
If you want to keep your flat chaining syntax instead of nesting, you can use an object from the parent scope to share:
如果要保留扁平链接语法而不是嵌套,可以使用父作用域中的对象进行共享:
var shared = {};
var promise = firstQuery.get(objectId).then(function(result1){
// save results to shared object
shared.result1 = result1;
return secondQuery.find();
}).then(function(result2){
shared.result2 = result2;
return thirdQuery.find();
}).then(function(result3) {
// here I want to use "result1", "result2" and "result3"
// just use shared.result1, shared.result2
});