У меня проблема с обещаниями и циклом. Следующий код не выполняется последовательно:
secondQuery.find().then(function(results) {
alert("2")
for (var i in results) {
(function(index){
var object = results[index];
var item_id = results[index].id;
var status = object.get("status");
var event_id = object.get("event_id");
var user_id = object.get("user_id");
var user_id_name = object.get("user_id_name");
var thumbimageurl = "";
var nFacebookFriends = 0;
var nInstagramFollowers = 0;
var nTwitterFollowers = 0;
var query2 = new Parse.Query(User)
query2.equalTo("username",user_id)
return query2.first({
success: function(object) {
alert("3")
var thumbfile = object.get("thumb");
thumbimageurl = thumbfile.url();
nFacebookFriends = object.get('nFacebookFriends');
nInstagramFollowers = object.get('nInstagramFollowers');
nTwitterFollowers = object.get('nTwitterFollowers');
}
}).then(function(){
alert("4")
requests.push({
'thumb': thumbimageurl,
'item_id':item_id,
'status':status,
'event_id':event_id,
'user_id':user_id,
'user_id_name':user_id_name,
'nFacebookFriends':nFacebookFriends,
'nInstagramFollowers':nInstagramFollowers,
'nTwitterFollowers':nTwitterFollowers
})
})
})(i)
}
}).then(function(){
alert('end')
$scope.requests = requests;
$localStorage.requests = requests;
// alert(JSON.stringify(requests))
})
После предупреждения "2" вместо цикла "3" и "4" я получил прямо "конец". Есть ли способ заставить цикл for выполнить до следующего обещания?
Вы можете создать цепочку обещаний, и каждый из них ожидает выполнения предыдущего обещания в цепочке. поэтому внутри каждой итерации цикла for вы можете продолжать добавлять promises
в promise chain
.
Примечание. Но у меня проблема @query2.first
это возвращает обещание, а также обратный вызов? в этом случае я не знаю, что происходит с частью обратного вызова.
secondQuery.find().then(function(results) {
alert("2");
// We will create a chain of promises here,
// Each of it is pending on previouse promise in the chain
var promise = Promise.resolve();
for (var i in results) {
(function(index) {
promise = promise.then(function() {
var object = results[index];
var item_id = results[index].id;
var status = object.get("status");
var event_id = object.get("event_id");
var user_id = object.get("user_id");
var user_id_name = object.get("user_id_name");
var thumbimageurl = "";
var nFacebookFriends = 0;
var nInstagramFollowers = 0;
var nTwitterFollowers = 0;
var query2 = new Parse.Query(User);
query2.equalTo("username",user_id);
//I am not very sure about this, this return a promise also there is a callback
//So When callback hits is out of this scope
return query2.first({
success: function(object) {
alert("3")
var thumbfile = object.get("thumb");
thumbimageurl = thumbfile.url();
nFacebookFriends = object.get('nFacebookFriends');
nInstagramFollowers = object.get('nInstagramFollowers');
nTwitterFollowers = object.get('nTwitterFollowers');
}
})
})
.then(function() {
alert("4");
requests.push({
'thumb': thumbimageurl,
'item_id':item_id,
'status':status,
'event_id':event_id,
'user_id':user_id,
'user_id_name':user_id_name,
'nFacebookFriends':nFacebookFriends,
'nInstagramFollowers':nInstagramFollowers,
'nTwitterFollowers':nTwitterFollowers
})
})
})(i)
}
return promise;
})
.then(function(){
alert('end');
$scope.requests = requests;
$localStorage.requests = requests;
// alert(JSON.stringify(requests))
})
Вам нужно понять, как происходят асинхронные вызовы. Что происходит здесь, так это то, что выполняется внешний блок (secondQuery.find().then...
), и когда обещание возвращается, обратный вызов выполняется синхронно (все итерации цикла обгоняют разные асинхронные вызовы), а затем выходит, для выполнения блока then
который содержит alert('end')
; потому что в вашем коде я query2.first
что query2.first
- это асинхронный вызов, который не должен возвращаться до вызова end
блока.
если вы хотите, чтобы end
блок появился после 3
и 4
, вам придется привязать его к ним. Это единственный способ гарантировать желаемую последовательность. Или вы можете искать prom.all() (если ваша библиотека использует bluebird) или prom.all() (es6)