我编写了一系列函数,其中包括解析查询:
var query1 = new Parse.Query(Events);
query1.equalTo("id_organizer", $localStorage.username);
query1.greaterThanOrEqualTo("date_start",currentTime)
query1.each(function(results){
var object = results;
eventname = object.get("event_name");
datestart = object.get("date_start");
location = object.get("location");
id_event = object.get("id_event")
eventimagefile = object.get("event_image");
eventimageurl = eventimagefile.url();
description = object.get("description");
id_organizer = object.get("id_organizer");
min_twitter_followers = object.get("min_twitter_followers");
min_instagram_followers = object.get("min_instagram_followers");
min_facebook_friends = object.get("min_facebook_friends");
max_number_requests = object.get("max_number_requests");
eventDetails.push({'name':eventname,'location':location, 'datestart':datestart, 'eventphoto':eventimageurl,'organizer':id_organizer, 'description':description, 'minTwitterFollowers':min_twitter_followers, 'minFacebookFriends':min_facebook_friends, 'minInstagramFollowers':min_instagram_followers,'maxNumberRequests':max_number_requests, 'id_event':id_event})
}).then(function(){
alert("start")
var Attendees = Parse.Object.extend("Attendees");
eventDetails.forEach(function(e){
var query2 = new Parse.Query(Attendees);
query2.equalTo("event_id", e.id_event);
query2.count({
success: function(number) {
e["n_requests_received"] = number;
alert("received")
}
})
var query3 = new Parse.Query(Attendees);
query3.equalTo("event_id", e.id_event);
query3.equalTo("status", "confirmed")
query3.count({
success: function(number) {
e["n_requests_confirmed"] = number;
// alert("confirmed")
}
})
})
}).then(function(){
alert("end")
alert(JSON.stringify(eventDetails))
$scope.events = eventDetails;
$localStorage.events = eventDetails;
});
})
不幸的是,在"开始"之后立即打印警报"结束",而不等待foreach循环中的查询(query1、query2)执行。你知道我如何在下一个查询之前执行两个查询来进行for循环吗?
.then(function(){
alert("start")
var Attendees = Parse.Object.extend("Attendees");
return Promise.all(eventDetails.map(detail => {
return Promise.all([new Promise((res, rej) => {
var query2 = new Parse.Query(Attendees);
query2.equalTo("event_id", detail .id_event);
query2.count({
success: function(number) {
detail["n_requests_received"] = number;
alert("received")
res('Some value if required'); //These are needed or promise chain will hang
}
});
}),
new Promise((res, rej) => {
var query3 = new Parse.Query(Attendees);
query3.equalTo("event_id", detail .id_event);
query3.equalTo("status", "confirmed")
query3.count({
success: function(number) {
detail["n_requests_confirmed"] = number;
// alert("confirmed")
res('Some value if required'); //These are needed or promise chain will hang
}
});
})]);
}));
})
承诺链将等待承诺。也就是说,如果链中任何位置的.then
接收到未解决的承诺,它将等待该承诺得到解决。
因此,您可以使用Promise.all
,它需要一个promise数组,并在它们执行时解析。因此,映射到您的数组eventDetails
上,从每个单元格创建promise。在每个单元格中,使用另一个Promise.all
为两个Query
对象创建两个新的promise。
这样,您的.then
将等待eventDetails
的承诺数组得到解决。然后eventDetails
中的每个单元格都将等待您的查询数组解析。
注意:我们正在创建promise的new Promise()
。它会通过两次回调来解决或拒绝承诺。这就是在promise中包装旧回调样式API的方法。然而,如果你不调用它们中的任何一个来解决或拒绝,那么整个承诺链可能会挂起(取决于其设计),等待该承诺解决。
希望这是有道理的。这是伪代码,但你应该明白。
免责声明我没有使用Parse.Query
我不知道它是什么。然而,这个方法是我如何处理使用旧回调风格API的上述程序流的,在那里你基本上有嵌套的循环。
额外免责声明:我的例子是使用ES6语法。并不是所有的浏览器(IE)都支持这个功能。
编辑:操作要求一个不使用ES6箭头功能的版本,所以你来了。StackOverflow上有很多关于箭头函数、那个和谷歌的信息。正如你所看到的,在语法方面没有太大的区别。它的力量来自于它如何绑定作用域,以及当你以更实用的风格编写代码时。
.then(function(){
alert("start")
var Attendees = Parse.Object.extend("Attendees");
return Promise.all(eventDetails.map(function (detail) {
return Promise.all([new Promise(function (res, rej) {
var query2 = new Parse.Query(Attendees);
query2.equalTo("event_id", detail .id_event);
query2.count({
success: function(number) {
detail["n_requests_received"] = number;
alert("received")
res('Some value if required'); //These are needed or promise chain will hang
}
});
}),
new Promise(function (res, rej) {
var query3 = new Parse.Query(Attendees);
query3.equalTo("event_id", detail .id_event);
query3.equalTo("status", "confirmed")
query3.count({
success: function(number) {
detail["n_requests_confirmed"] = number;
// alert("confirmed")
res('Some value if required'); //These are needed or promise chain will hang
}
});
})]);
}));
})