我正在尝试创建一个排名,在该排名中,将为每个对象分配一组描述其排名的属性(适用于多次读取和少量写入)。
这是我创建的:
exports.calculateRanking = functions.firestore.document('players/{playerId}').onUpdate((change, context) => {
if (typeof change.before.data().score === 'undefined' && change.after.data().score > 0) {
var db = admin.firestore();
var batch = db.batch();
return db.collection("players").orderBy("score", "desc").get().then(snapshot => {
var docs = snapshot.docs;
var map = {};
for (var i = 0; i < docs.length; i++){
var player = docs[i];
var position = i + 1;
var industry = player.industry;
var age = player.age;
if (map[industry] !== null){
map[industry] += 1;
}
else{
map[industry] = 1;
}
if (map[age] !== null){
map[age] += 1;
}
else{
map[age] = 1;
}
if (map[industry+age] !== null){
map[industry+age] += 1;
}
else{
map[industry+age] = 1;
}
console.log(player.name);
return player.ref.collection("rankings").get().then(rankings => {
return rankings.docs.forEach(ranking => {
console.log("Inside ranking loop");
var currGeneralRanking = ranking.data().generalRanking.curr;
var currIndustryRanking = ranking.data().industryRanking.curr;
var currAgeRanking = ranking.data().ageRanking.curr;
var currIndustryAgeRanking = ranking.data().industryAgeRanking.curr;
var newGeneralRanking = position;
var newIndustryRanking = map[industry];
var newAgeRanking = map[age];
var newIndustryAgeRanking = map[industry+age];
var newCurrGeneral;
var newCurrIndustry;
var newCurrAge;
var newCurrIndustryAge;
var newPrevGeneral;
var newPrevIndustry;
var newPrevAge;
var newPrevIndustryAge;
if (currGeneralRanking !== 0){
if (newGeneralRanking !== currGeneralRanking){
newPrevGeneral = currGeneralRanking;
}
else{
newPrevGeneral = ranking.data().ranking.prev;
}
}
else {
newPrevGeneral = newGeneralRanking;
}
newCurrGeneral = newGeneralRanking;
if (currIndustryRanking !== 0){
if (newIndustryRanking !== currIndustryRanking){
newPrevIndustry = currIndustryRanking;
}
else{
newPrevIndustry = ranking.data().industryRanking.prev;
}
}
else{
newPrevIndustry = newIndustryRanking;
}
newCurrIndustry = newIndustryRanking;
if (currAgeRanking !== 0) {
if (newAgeRanking !== currAgeRanking) {
newPrevAge = currAgeRanking;
}
else{
newPrevAge = ranking.data().ageRanking.prev;
}
}
else{
newPrevAge = newAgeRanking;
}
newCurrAge = newAgeRanking;
if (currIndustryAgeRanking !== 0) {
if (newIndustryAgeRanking === currAgeIndustryRanking){
newPrevIndustryAge = currAgeIndustryRanking;
}
else{
newPrevIndustryAge = ranking.data().industryAgeRanking.prev;
}
}
else{
newPrevIndustryAge = newIndustryAgeRanking;
}
newCurrIndustryAge = newIndustryAgeRanking;
return batch.update(ranking.ref, {
"generalRanking": {
"curr": newCurrGeneral,
"prev": newPrevGeneral
},
"industryRanking": {
"curr": newCurrIndustry,
"prev": newPrevIndustry
},
"ageRanking": {
"curr": newCurrAge,
"prev": newPrevAge
},
"industryAgeRanking": {
"curr": newCurrIndustryAge,
"prev": newPrevIndustryAge
}
});
});
}).catch(error => {
return console.log(error);
});
}
return batch.commit().then(result => {
return console.log(result);
}).catch(error => {
return console.log(error);
});
}).then(result => {
return console.log('Transaction success', result);
}).catch(err => {
return console.log('Transaction failure:', err);
});
}
return;
});
虽然循环只运行一次。似乎(很明显)循环内的返回中断了它。
那么如何做出承诺?我正在考虑对一系列Promise.all()
的承诺进行ranking
的交易。然后问题就变成了从map
到每个ranking
集合的位置匹配。这样可以使map
映射到字典/哈希图,并且每个键对应于每个玩家的ID。不过,在集合ranking
中创建文档仅同时映射到玩家的ID也很糟糕。
所以,我的问题是,如果确实是只有Promise.all()
才能解决循环问题,我如何制作每个ranking
集合,将其输出到下一个Promise的then(rankings =>
会很好地知道它属于哪个玩家?