【问题标题】:Sequencing Async Call in For Loop - Javascript在 For 循环中对异步调用进行排序 - Javascript
【发布时间】:2023-03-29 14:25:01
【问题描述】:

我遇到了 for 循环中的异步调用问题。循环在异步调用完成之前继续。我对这种语言很陌生,并试图掌握回调..等。我尝试了一个自调用函数、promise 和 timeout,但仍然无法让流程按预期工作。

我希望在配置文件对象被推送到消息数组之前完成对 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);
}

感谢任何帮助或指导。

谢谢, 诺埃尔

【问题讨论】:

  • 您是否尝试过在value 事件处理程序中包含chat.messages.push(profile);
  • 正确。那解决了它。感谢您花时间查看和回复 :-) 如此简单,但让我头疼了好几个小时!

标签: javascript angularjs ionic-framework firebase firebase-realtime-database


【解决方案1】:

所以听起来你实际上想要两件不同的事情,一是你希望你的循环在异步调用完成之前不继续。我很确定 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);
                }

【讨论】:

  • 你好丹尼尔。谢谢回复的小伙伴。在执行类似的数据流时,我将采用这种格式。一直在尝试习惯来自顺序编码背景的异步编程。把它放在值事件处理程序中就可以了。非常感谢。
  • 没问题,不过请考虑选择一个答案。
【解决方案2】:

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);
});

【讨论】:

    【解决方案3】:

    我认为 .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
        });
    }
    

    【讨论】:

      【解决方案4】:

      在值事件处理程序中推送到数组:

      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); 
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-12-16
        • 1970-01-01
        • 2012-10-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-04
        • 1970-01-01
        相关资源
        最近更新 更多