2

forループの非同期呼び出しに問題があります。ループは、非同期呼び出しが終了する前に継続します。私はこの言語にはかなり新しく、コールバックなどを把握しようとしています。私は自己呼び出し関数、約束、タイムアウトを試みましたが、意図したとおりに動作するようにフローを取得することはできません。Forループの非同期呼び出しのシーケンス - Javascript

プロファイルオブジェクトがメッセージ配列にプッシュされる前に、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); 
} 

お気軽にお問い合わせください。あなたが実際には2つの別々のものにしたいよう

おかげで、 ノエル

+0

あなたは 'chat.messages.push(プロファイル)を含めてみまし;' [値]イベントハンドラ内で? – guest271314

+0

スポットがあります。それはそれを修正した。見て、応答する時間を取ってくれてありがとう:-)シンプルだけど、何時間も頭を叩いていました! –

答えて

1

だから、それはあなたがあなたのループは非同期呼び出しが完了するまで継続しないようにしたい、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); 
       } 
+0

こんにちはダニエル。仲間に応答してくれてありがとう。私は同様のデータフローを実行するときにこのフォーマットを採用します。シーケンシャルコーディングのバックグラウンドから来ているように、非同期プログラミングに慣れようとしていました。それを価値のあるイベントハンドラに入れることがそのトリックでした。どうもありがとう。 –

+0

問題はありませんが、回答を選択することを検討してください。 –

1

私は.ALL方法はこのような何かを移動するための方法だと思いますchat.messages.push(profile)value内のハンドラ

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

を含めます。たとえば、次のように

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

値イベントハンドラ内の配列にプッシュ:

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); 
}); 
関連する問題