0
supportChat: function(){ 
    return functions.https.onRequest((req, res) => { 
     var userId = req.query.userId; 
     var object = {}; 
     db.ref("https://stackoverflow.com/users/-KwZ2N38Q6a1a87p982/threads").orderByKey().once('value').then(function(snapshot) { 
      var snap = snapshot.val(); 
      var keys = Object.keys(snap); 

      for (var i = 0; i < keys.length; i++){ 
       k = keys[i]; 
       db.ref("/threads/"+k+"/lastMessage").orderByKey().once('value').then(function(snapshot){ 
        var snapshot = snapshot.val(); 
        if (snapshot[i]["sender"] != "-KwZ2N38Q6a1a87p982"){ 
         object[snap[i]["messageID"]] = snapshot; 
        } 
       }); 
      } 
      console.log(object); 
      return res.status(200).send(object); 
     }); 
    }); 
}, 

내 데이터베이스의 각 사용자에게는 스레드 채팅 아이디가 있습니다.이 아이는 그들이 가고있는 모든 채팅 스레드를 보여줍니다. 그런 다음 해당 스레드의 모든 데이터가있는 다른 스레드 섹션이 데이터베이스에 있습니다.for 루프 내에서 중첩 데이터베이스 쿼리는 어떻게 수행합니까?

내가하려는 일은 스레드의 마지막 메시지가 나 (현재 사용자)가 보내지 않은 모든 스레드를 찾기 위해 특정 사용자의 스레드 ID를 데이터베이스의 스레드 섹션과 비교하는 것입니다.

왜 내가이 문제로 고민하고 있는지 알 수 없습니다. 내 조건을 충족시키는 각 스레드의 모든 snapshot.val()을 한 번에 끝점으로 보낼 수있는 올바른 방법은 무엇입니까? 어쩌면 내 접근 방식이 꺼져있을 수 있습니다.

답변

1

for 루프의 모든 약속이 언제 완료되는지 알고 싶으면 루프에서 가져온 약속 배열을 누적 한 다음 Promise.all()을 사용하여 모두 완료된 경우를 알 수 있습니다.

은 또한 비동기 .then() 핸들러가 호출 될 때 여전히 올바른 있도록 for 루프의 각 호출은 고유의 색인을 유지 있도록 for 루프 인덱스를 보호해야합니다. for 루프를 전환하여 var i 대신 let i을 사용하면됩니다. 코드에

supportChat: function(){ 
    return functions.https.onRequest((req, res) => { 
     let userId = req.query.userId; 
     let object = {}; 
     db.ref("https://stackoverflow.com/users/-KwZ2N38Q6a1a87p982/threads").orderByKey().once('value').then(function(snapshot) { 
      let snap = snapshot.val(); 
      let keys = Object.keys(snap); 
      let promises = []; 

      for (let i = 0; i < keys.length; i++){ 
       let k = keys[i]; 
       promises.push(db.ref("/threads/"+k+"/lastMessage").orderByKey().once('value').then(function(snapshot){ 
        let snapshot = snapshot.val(); 
        if (snapshot[i]["sender"] != "-KwZ2N38Q6a1a87p982"){ 
         object[snap[i]["messageID"]] = snapshot; 
        } 
       })); 
      } 
      return Promise.all(promises).then(() => { 
       console.log(object); 
       return res.send(object); 
      }); 
     }).catch(err => { 
      console.log(err); 
      return res.sendStatus(500); 
     }); 
    }); 
}, 

기타 의견 : 당신이 실제로 supportChat() 기능에서 무언가를 반환하려는 경우

참고로, 그게 뭔지 지정하십시오. 지금 당장은 함수 호출에서 반환 할 것으로 예상되는 것이 명확하지 않습니다.


, 당신이의 .status(200) 부분이 필요하지 않습니다 : 모든 자체

res.send(object); 

을하고 자동으로 상태를 사용합니다 :

res.status(200).send(object); 

을 당신은 다만 수 200.


그리고 오류를 catch하고 오류 조건에서 응답을 보내려면 .catch() 처리기가 필요합니다.

+0

고마워요! 훨씬 더 견고 해 보인다! 나는 이것을 시험해 보았지만 실행했을 때, 하나의 메시지 객체 (하나의 결과) 만 반환했다. 하지만 수백 가지가 있습니다. 그게 잘못 될 수 있다고 생각합니까? – ryangineer

+0

@ryangineer - 내가 보여준 것처럼'for i'에서'var i'를'for' 루프로 변경 했습니까? 이는 모든 결과가 동일한 색인을 사용하지 않도록 요구됩니다. – jfriend00

+0

는 내 끝 부분에 작은 비틀기를 만들었습니다 (작은 오타). 그리고 그것을 얻었다! 이것은 놀랐다. 고맙습니다 youuuuuuu. – ryangineer