我有以下Angular 6代码,该代码运行Firestore事务以在用户单击上/下按钮时插入/更新/删除用户的投票。我如何确定交易是否成功提交?如果失败,runTransaction
会在底部的catch
块中抛出异常吗?
我问的原因是,当我缓慢单击向上/向下按钮时,代码可以正常工作,但是当我快速连续单击它们时会出现问题。我会在控制台中看到很多“ documents:commit 400()” HTTP错误消息,即使某些事务未提交,程序流似乎也将其移到then()
块中。
在错误处理方面我还能做些什么吗?
vote(username, recipeId, direction) {
let value;
let valueChange;
if ( direction == 'up' ) {
value = 1;
}
if ( direction == 'down' ) {
value = -1;
}
// assemble vote object to be recorded in votes collection
const voteObj: Vote = { username: username, recipeId: recipeId , value: value };
// get reference to vote document. Note custom path.
const votePath = `votes/${username}_${recipeId}`;
const voteDocRef = this.afs.doc(votePath).ref;
this.afs.firestore.runTransaction(transaction =>
transaction.get(voteDocRef).then(voteDoc => {
if (!voteDoc.exists) {
// This is a new vote, so add it to the votes collection
transaction.set(voteDocRef, voteObj);
valueChange = value;
} else {
const voteData = voteDoc.data();
if ( voteData.value == value ) {
// existing vote is the same as the button that was pressed, so delete
// the vote document
transaction.delete(voteDocRef);
valueChange = (-value);
} else {
// existing vote is the opposite of the one pressed, so update the
// vote doc
transaction.set(voteDocRef, voteObj);
valueChange = (value*2);
}
}
return valueChange;
}))
.then(valueChange => {
/* Success? */
console.log('valueChange ' + valueChange)
})
.catch(err => {
console.error(err)
});
}
更新:随着我对此的投入越来越大,我逐渐相信我发布的代码可以正确处理提交失败-或至少在以下情况下它才会到达then()部分:交易成功。我已经意识到,限制用户单击“ upvote” /“ downvote”按钮的速度几乎可以完全缓解问题,无论如何都是一件好事。因此,我在投票按钮上实现了一个自定义指令,该指令仅允许每秒单击一次。我基于https://coryrylan.com/blog/creating-a-custom-debounce-click-directive-in-angular上的代码,除了我使用debounceTime
而不是使用throttleTime
之外。