【问题标题】:Firebase Promise Order in forEachforEach 中的 Firebase 承诺顺序
【发布时间】:2017-03-25 06:07:58
【问题描述】:

下面的代码按这样的顺序工作

-->then 1 
-->then 2
-->then 3
-->then 3 ends
-->then 4
-->then 5
--> x
--> y
--> x
--> y
-->then 6

但我希望它是这样的:

-->then 1 
-->then 2
-->then 3
--> x
--> y
--> x
--> y
-->then 3 ends
-->then 4
-->then 5
-->then 6

这是代码: 问题出在 forEach 中。 如果我在 forEach 中有一次(“值”)的东西,我无法等待它的结果然后继续“然后 4”

   let massUpdate={};
let licenseLength=0;
let refOfferLength =admin.database().ref()...
refOfferLength.once("value")
    .then(lengthSnapshot=>{
        console.log(" then :1 ");
        //....
    }).then(snap=>{
    console.log(" then :2 ");
    let ref = admin.database().ref()....
    return ref.once("value");
}).then(ref=>{
    console.log(" then :3 ");
    ref.forEach(function(pSnapshot){
        let pId = pSnapshot.key;
        let pPath = pSnapshot.val();

        let refP = admin.database().ref().child("asd").child(event.params.userId).child(pPath).child(pId);
        refP.once("value").then(snap=>{
            console.log(" then :x ");
            //.....


            let path_license = "asd/" + event.params.userId+"/"+urunPath+"/"+urunId+"/license";
            let val_license = "open";
            //....

            massUpdate[path_license]=val_license;

        }).then(snap=>{console.log(" then :y ");});

    });
    console.log(" then :3 ends");


}).then(snap=>{// 
    console.log(" then :4 ");
    let pathOffersAndUsers = "kpss_offers_and_users/"+event.params.offerId+"/"+event.params.userId;
    let valOfferDetails = {"created_date": (moment().utcOffset(3).format("Y-MM-DD HH:mm:ss"))};
    massUpdate[pathOffersAndUsers]=valOfferDetails;

    return true;

}).then(snap=>{// 
    console.log(" then :5 ");

    let ref = admin.database().ref();
    return ref.update(massUpdate);

}).then(snap=>{
    console.log(" then :6 ");

    console.log(" Done : "+ event.params.userId + " : "+ event.params.offerId);


}).catch(function (error){console.log(" E : "+error+" : "+ event.params.userId + " : "+ event.params.offerId);});

【问题讨论】:

标签: firebase promise


【解决方案1】:

then 回调中,当您想要延迟then 链中的下一个then 回调直到该承诺解决时,您应该返回一个承诺。

确实在您的forEach 循环中有承诺,但它们的返回值却被遗忘了。您可以链接它们并使用reduce返回结果承诺:

return ref.reduce(function(prom, pSnapshot){ // return(!) a promise from reduce
    let pId = pSnapshot.key;
    let pPath = pSnapshot.val();

    let refP = admin.database().ref().child("asd").child(event.params.userId).child(pPath).child(pId);
    return prom.then(function () { // return(!) the promise, chained to the previous
        return refP.once("value");
    }).then(snap=>{ 
        console.log(" then :x ");
        //.....
        let path_license = "asd/" + event.params.userId+"/"+urunPath+"/"+urunId+"/license";
        let val_license = "open";
        //....
        massUpdate[path_license]=val_license;
    }).then(snap=>{console.log(" then :y ");});
}, Promise.resolve()) // start the promise chain with a resolved promise
.then(function () { // Chain one more `then` callback to report
    console.log(" then :3 ends");
});

根据您的循环承诺是否必须等待前一个解决,您还可以使用Promise.all,它允许并行创建所有承诺:

return Promise.all(ref.map(function(pSnapshot){ // pass an array of promises
    let pId = pSnapshot.key;
    let pPath = pSnapshot.val();

    let refP = admin.database().ref().child("asd").child(event.params.userId).child(pPath).child(pId);
    return refP.once("value").then(snap=>{ 
        console.log(" then :x ");
        //.....
        let path_license = "asd/" + event.params.userId+"/"+urunPath+"/"+urunId+"/license";
        let val_license = "open";
        //....
        massUpdate[path_license]=val_license;
    }).then(snap=>{console.log(" then :y ");});
}))
.then(function () { // Chain one more `then` callback to report
    console.log(" then :3 ends");
});

我刚刚提到了代码的相关部分,但您可以(并且应该)将最后一个 then 调用在主链中上移一级。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-10
    • 1970-01-01
    • 1970-01-01
    • 2016-11-23
    • 2019-06-16
    • 2015-12-22
    • 2017-08-18
    • 1970-01-01
    相关资源
    最近更新 更多