2016-07-28 150 views
0

我有一个Promise和for循环的问题。下面的代码不是顺序地执行:jascript angular for循环在promise后执行

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循环?

回答

0

您需要了解异步调用是如何发生的。这里发生的是最外面的块(secondQuery.find().then...)被执行,当promise返回时,回调被同步执行(循环的所有迭代激发不同的异步调用),然后退出,执行then块,其中包含alert('end') ;因为在您的代码中,我观察到query2.first是异步调用,在调用end块之前,该调用不得返回。

如果你想end块来的34后,你必须把它链到他们。这是保证你想要的序列的唯一方法。或者您可以查询promise.all()(如果您的图书馆使用蓝鸟)或promise.all()(es6)

0

您可以创建一个承诺链,并且它在链中的前一个承诺中都处于等待状态。因此在for循环的每次迭代中,您可以继续将添加到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)) 
})