forEach

时间:2017-03-24 05:34:57

标签: firebase promise

以下代码按此顺序工作

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

1 个答案:

答案 0 :(得分:0)

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调用在主链中向上移动一级。