以下代码按此顺序工作
-->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);});
答案 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
调用在主链中向上移动一级。