排序异步调用在For循环- Javascript

Sequencing Async Call in For Loop - Javascript

本文关键字:循环 Javascript For 异步 调用 排序      更新时间:2023-09-26

我在for循环中有一个异步调用的问题。循环在异步调用结束之前继续。我对这门语言很陌生,并试图掌握回调等等。我已经尝试了一个自调用函数,承诺和超时,但仍然不能得到流工作的预期。

我希望在概要文件对象被推入消息数组之前完成对firebase的调用。

// returns the chats for that profile
Chat.allChatsByUser(uid).$loaded()
 .then(function(data) {     
   for (var i = 0; i < data.length; i++) {
   // self calling function for async callback handling
   // this ensures that the async call is run for every iteration in the loop
   (function(i) {
      var item = data[i];
      // function to arrange users and chats fom newest to oldest
      // for each matched user. item.$id = uid              
      Auth.getProfile(item.$id).$loaded()
      .then(function(profile) { 
         // first function handles success
         if (typeof profile === 'object') { 
              if(chat.keyOrder == 'true') {
              // get last chat from firebase
              // WANT THIS COMPLETE BEFORE CONTINUING                       
              ref.child('chatting').child('messages').child(chat.chatId).on("value", function(data) {
                 profile.lastChat = data.child('lastMsg').val();
              });
             // pushes chatting users profile into the array
             chat.messages.push(profile);    
         } else {
               // invalid response
               return $q.reject(profile);
         }
 }, function(profile) {
   // promise rejected
   console.log('error', error);});
 // i argument as closure
 })(i);
}

感谢您的帮助和指导。

谢谢,诺尔

听起来你想要两个独立的东西,一,你想要你的循环直到async调用完成后才继续。我很确定有一些奇特的方法可以在es6中做到这一点,但你没有使用es6。我不知道你为什么想让循环等待?所以我临时使用了一个while循环。其次,您希望"在概要文件对象被推入消息数组之前完成对firebase的调用"。这是通过将推送调用放在第一个注释中提到的value事件处理程序中来实现的。

// returns the chats for that profile
Chat.allChatsByUser(uid).$loaded()
    .then(function(data) {
            var i = 0;
            var inProgress = false;
            while (i < data.length) {
                // self calling function for async callback handling
                // this ensures that the async call is run for every iteration in the loop
                // wait until last iteration has completed
                while(inProgress);
                // the function is about to begin
                inProgess = true;
                (function(i) {
                        // increment i here
                        var item = data[i++];
                        // function to arrange users and chats fom newest to oldest
                        // for each matched user. item.$id = uid              
                        Auth.getProfile(item.$id).$loaded()
                            .then(function(profile) {
                                    // first function handles success
                                    if (typeof profile === 'object') {
                                        if (chat.keyOrder == 'true') {
                                            // get last chat from firebase
                                            // WANT THIS COMPLETE BEFORE CONTINUING                       
                                            ref.child('chatting').child('messages').child(chat.chatId).on("value", function(data) {
                                                profile.lastChat = data.child('lastMsg').val();
                                                // wait until event
                                                // pushes chatting users profile into the array
                                                chat.messages.push(profile);
                                                // allow next iteration to continue
                                                inProgess = false;
                                            });
                                        } else {
                                            // invalid response
                                            return $q.reject(profile);
                                        }
                                    },
                                    function(profile) {
                                        // promise rejected END script
                                        return console.log('error', error);
                                    });
                                // i argument as closure
                            })(i);
                }

value处理程序中包含chat.messages.push(profile)

ref.child('chatting').child('messages').child(chat.chatId)
.on("value", function(data) {
  profile.lastChat = data.child('lastMsg').val();
  // pushes chatting users profile into the array
  chat.messages.push(profile);
});

我认为。all方法是这样做的方式。例如:

function loadMeetings(city,state) {
    return ref.child('states').child(state).child(city).once('value').then(function(snapshot) {
    var reads = [];
    snapshot.forEach(function(childSnapshot) {
        var id = childSnapshot.key();
        var promise = ref.child('meetings').child(id).once('value').then(function(snap) {
            return snap.val();
        }, function(error) {
            // The Promise was rejected.
            console.error(error);
        });
        reads.push(promise);
    });
    return Promise.all(reads);
    }, function(error) {
        // The Promise was rejected.
        console.error(error);
    }).then(function(values) {
        //for each snapshot do something
    });
}

将值事件处理程序内的数组推送:

ref.child('chatting').child('messages').child(chat.chatId)
 .on("value", function(data) {
    profile.lastChat = data.child('lastMsg').val();
    // pushes chatting users profile into the array
    chat.messages.push(profile); 
});