在我的Parse Cloude代码中,我需要运行几个连续的查询,每个查询都使用“find()”。
示例:
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"
});
问题是:如何在最后的“then”语句中访问“result1”和“result2”,而不将它们分配给父作用域中声明的变量。
为什么我这样问:如果要在循环中创建一堆promises以便它们并行执行,那么你就不能使用父作用域技巧(想象一下围绕上述语句的for循环所有将promise放入一个数组中,然后使用“Parse.Promise.when”进行评估。它们都将同时开始修改父作用域变量。)
我可以创建某种承诺对象,我可以返回以下内容:
Parse.promise({result:result1,findResult:secondQuery.find()};
所以我可以通过
从“result2”参数中获取值result2.result
和
result2.findResult
我希望我能说清楚。这不是很容易解释的。
答案 0 :(得分:24)
您可以使用closures来执行此操作,而无需任何额外的对象或包装。
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
});
});
});
这种“嵌套”语法在功能上与“链接”语法相同。
根据评论编辑
如果您的承诺链冗长而复杂,以至于这种嵌套语法变得笨拙,那么逻辑可能足够复杂,值得将抽象转化为自己的函数。
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
});
就我个人而言,我认为这比阅读.bind
更容易阅读和维护。
答案 1 :(得分:12)
您不能使用父范围技巧
好吧,既然其他答案都是这样做的,那么让我建议一个没有的解决方案。你可以传递已解决的承诺。这也具有无嵌套或封闭的额外好处。
这是基于promises已经代表值的概念,所以你实际上 没有创建一个长链:
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"
});
在标准承诺中,而不是解析代码,这看起来很相似:
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"
});
使用bluebird,您可以使用.spread
获取快捷方式或.bind
或实际上下文。如果你绝对必须创建一个链,你可以通过使用Promise.all返回多个promise来传递上下文,但我相信这种方法更可取。
答案 2 :(得分:1)
如果要保留扁平链式语法而不是嵌套,可以使用父作用域中的对象进行共享:
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
});