因此,我目前正在运行一些脚本来重置我们一个应用程序中的用户余额。我正在使用Firestore来获取所有任务,然后根据每个用户的需求来计算余额。听起来很简单吧?应该是,不是。问题在于,由于对同一文档的写冲突,事务正在中止。之所以发生这种情况,是因为所有任务都同时传递给了事务。
我尝试使用forEach方法,这导致他们中止,因为它每次都尝试更新同一用户记录。 而且我尝试了(让任务任务执行),这给了我一个错误“无法完成任务”。
async function updatestuff(){
console.log("start");
const tasksRef = db.collection('tasks');
try {
const allTasksSnapShot = await tasksRef.get();
allTasksSnapShot.forEach(async(doc) => {
//Run transaction for calculations for each task here
const tskUser = doc.data().taskUser;
const tuser = db.collection('backupusers').doc(tskUser);
if(doc.data().taskStatus == 'Not Completed'){
console.log('NOT');}
if(doc.data().taskStatus != 'Not Completed'){
console.log('Run transaction here and wait for it to finish?');
await db.runTransaction(async t => {
const userSnapShot = await t.get(tuser);
if (!userSnapShot) {return console.log('not a thing')}
//get new balance calculated
const newBalance = userSnapShot.actualbalance + doc.data().taskBalanceAdj;
await t.update(tuser, {actualbalance: newBalance});
})
}});
console.log("end")
}
catch (err) {
console.log('Error getting documents', err);
}
}
当前,文档写入之间的冲突导致事务中途终止。
如果有人可以帮助我以异步方式将每个任务传递给事务,等待事务完成,然后再传递下一个任务,我将非常感激。 或将获得相同结果的另一种方法。...
预先感谢您好心善良的灵魂!
答案 0 :(得分:0)
您的updatestuff
函数启动了许多异步工作,但是并没有返回一个承诺,当它们全部完成后,它就可以解决。您将在主触发器函数中使用该承诺,以使Cloud Functions知道所有工作已完成,并且可以安全地清理所有内容。如果您不这样做,那么您的功能可能会在工作完成之前被关闭。
请记住,对forEach使用async / await并不是一个好主意。在继续进行下一项之前,forEach函数不会等待异步工作完成。随着大量交易的进行,它将结束,而无法知道何时完成所有交易。相反,您可能不希望使用async / await,而是将所有交易承诺推送到一个数组中,然后在该数组上使用Promise.all()创建一个新的承诺,当所有工作完成。从函数中返回它,然后在主触发器函数中使用它。