Jascript угловой для цикла выполняется после обещаний

0

У меня проблема с обещаниями и циклом. Следующий код не выполняется последовательно:

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-loop
promise

2 ответа

0

Вы можете создать цепочку обещаний, и каждый из них ожидает выполнения предыдущего обещания в цепочке. поэтому внутри каждой итерации цикла 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))
})
0

Вам нужно понять, как происходят асинхронные вызовы. Что происходит здесь, так это то, что выполняется внешний блок (secondQuery.find().then...), и когда обещание возвращается, обратный вызов выполняется синхронно (все итерации цикла обгоняют разные асинхронные вызовы), а затем выходит, для выполнения блока then который содержит alert('end'); потому что в вашем коде я query2.first что query2.first - это асинхронный вызов, который не должен возвращаться до вызова end блока.

если вы хотите, чтобы end блок появился после 3 и 4, вам придется привязать его к ним. Это единственный способ гарантировать желаемую последовательность. Или вы можете искать prom.all() (если ваша библиотека использует bluebird) или prom.all() (es6)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню