0

참고 : 과 비슷한과 유사한 질문이 이미 있습니다. 읽었지만 여전히 시나리오가 어려워요.Firebase DB 비동기 콜백을 사용하여 중첩 루프에서 Q 지연된 약속을 체인화하는 방법

필자는 (Google) Firebase Cloud 기능을 사용하여 루프 내에서 특정 순서로 많은 쿼리를 실행해야합니다. 이런 식으로 뭔가 예를 들어 (LodashQ 사용) : 각 사용자에 대해

let users = [foo, bar, baz, qux, etc, ...]; 
let myPromises = []; 

_.each(users, function (user) { 

    // Query A (async) 
    let queryA = function() { 
     let deferred = Q.defer(); 
     let _queryA = function() { 
      admin.database().ref('blah').child(blah).once("value", function(snapshot) { 
       // logic 
       return deferred.resolve(); 
      }); 
     }; 
     _queryA(); 
     return deferred.promise; 
    }; 

    // Query B (async) 
    let queryB = function() { 
     let deferred = Q.defer(); 
     let _queryB = function() { 
      admin.database().ref('blah').child(blah).once("value", function(snapshot) { 
       // logic 
       return deferred.resolve(); 
      }); 
     }; 
     _queryB(); 
     return deferred.promise; 
    }; 

    // Query C (async) with nested (async) query loop 
    let queryC = function() { 
     let deferred = Q.defer(); 
     let _queryC = function() { 
      admin.database().ref('blah').child(blah).once("value", function(snapshot) { 
       // logic 

       let potatoPromises = []; 

       // another query loop 
       _.each(snapshot.val(), function (potato) { 
        let potato_deferred = Q.defer(); 
        admin.database().ref('blah').child(potato.id).once("value", function(potato_snapshot) { 
         // logic 

         return potato_deferred.resolve(); 
        }); 
        potatoPromises.push(potato_deferred.promise); 
       }); 

       Q.all(potatoPromises).then(function() { return deferred.resolve() }); 
      }); 
     }; 
     _queryC(); 
     return deferred.promise; 
    }; 

    // Function D (sync) 
    let functionD() = function() { 
     let deferred = Q.defer(); 
     let _functionD = function() { 
      // logic 
     }); 
     _functionD(); 
     return deferred.promise; 
    }; 

    myPromises.push(Q.all([queryA(),queryB()]).then(queryC()).then(functionD())); 

}); 

Q.all(myPromises).then(function() { 
    // Final logic ran only once after all promises in loop are resolved 
}); 

통해 반복, queryC는 (임의의 순서로 실행할 수있는, 따라서 Q.all()가) 완료 queryAqueryB 둘 때까지 시작 기다려야합니다, functionDqueryC까지 기다려야합니다. I

트릭을 할 것 코드 위의 생각,하지만 난 클라우드 기능을 실행할 때, queryA, queryB, queryCfunctionD 모두 즉시 시작하고있다. 나를 위해 일하는입니다 것을

유일한 약속은 최종 논리가입니다 맨 끝에서 한 번 달려있다 대기 I처럼 시작하기 전에 queryA, queryB, queryCfunctionD 원하는 그것을 대하지만 논리 최종 기능의 내부에 각각 user에 대해 결정된 정보가 queryCfunctionD에 있으므로 제대로 작동하지 않습니다.

아이디어가 있으십니까? 감사합니다 :)

+3

'그 때는 (queryC())'즉시 호출'queryC' ... 당신은 '그 때는 원하는 (queryC)'.. . etc - 참고 :'.then' 인수는 함수를 호출 한 결과가 아닌 함수 여야합니다. (물론 호출 된 함수가 아주 좋은 함수를 반환하지만 함수가 함수를 반환하지 않는 경우) –

+1

in 요약 - myPromises.push (Q.all ([queryA(), queryB()]). then (queryC) .then (functionD))'는 의도 한 것과 더 가깝습니다. 그러나 코드가 크게 'firebase' 메쏘드가 이미 약속을 리턴한다고 확신하기 때문에 단순화되었습니다. –

+0

오케이, 이제 시도해 보겠습니다. 파이어베이스 쿼리에 관해서는 당신이 옳다고 생각합니다. 방금 https://firebase.googleblog.com/2016/01/keeping-our-promises-and-callbacks_76.html을 읽고 어떻게 사용하는지 보여줍니다. – WillB

답변

2

하려고하면 호출하는 C 및 D :

myPromises.push(Q.all([queryA(),queryB()]).then(queryC).then(functionD));