我的要求有一些变化:
不仅创建/请求/取消整个要约,还对要约的详细信息执行一些操作:
这是activeOffers列表中的一个报价:
activeOffers
-LKohyZ58cnzn0vCnt9p
details
direction: "city"
seatsCount: 2
timeToGo: 5
uid: "-ABSIFJ0vCnt9p8387a" ---- offering user
用户应该能够“要求座位”,并且如果成功,则优惠记录应如下所示:
activeOffers
-LKohyZ58cnzn0vCnt9p
details
direction: "city"
seatsCount: 1 ----- reduced count
timeToGo: 5
uid: "-ABSIFJ0vCnt9p8387a"
deals
-GHFFJ0vCnt9p8345b ----- the userId of asking user
seatsCount: 1
status: "asked"
但是执行如下所示的源代码后,我遇到了3个问题:
(如上图所示,优惠有2个席位,用户要求1个席位)
在我的日志中执行后,我同时拥有“减少席位数减1”和“席位不足” ...即:“ if-then-else”的“ then”和“ else”部分: o
函数结果为[]-即未创建交易。
我不确定该如何执行TODO:部分-使用询问userId作为KEY在DealsRef下添加子项(新的交易对象),因为我认为这里不需要自动生成的密钥。
输入数据具有以下结构:
data
"uid": "-GHFFJ0vCnt9p8345b", ----- the userId of asking user
"id": "-LKohyZ58cnzn0vCnt9p", ----- the id of offer
"details":
"seatsCount": 1
这是我的代码:
dealSeats = function(data) {
const TAG = '[dealSeats]: ';
var details = data.details;
var info = data.info;
var entryRef = db.ref('activeOffers/' + data.id);
var entryDetailsRef = entryRef.child('details');
var seatsCountRef = entryDetailsRef.child('seatsCount');
var success = false;
return seatsCountRef.transaction((current)=>{
var value = current;
if (value >= details.seatsCount) {
success = true;
value = value - details.seatsCount;
console.log(TAG + 'Reducing seats count by ' + details.seatsCount);
} else {
console.log(TAG + 'Not enought seats');
}
return value;
})
.then(()=>{
var deal = [];
if (success) {
console.log(TAG + 'Succes');
deal.seatsCount = details.seatsCount;
deal.status = 'asked';
// TODO: here should add the new deal to dealsRef
return deal;
} else {
console.log(TAG + 'Failure');
return deal;
}
})
}
正如您所看到的-我不确定检查交易是否成功的正确方法是什么...
答案 0 :(得分:1)
reference documentation for DatabaseReference.transaction
says:
...,直到成功写入而没有冲突或通过不从更新函数返回值来中止事务。
所以中止事务的方法是不从更新函数返回任何值。这意味着整个第一块可以简化为:
seatsCountRef.transaction((current)=>{
if (current >= details.seatsCount) {
return value - details.seatsCount;
}
})
现在,它要么返回新值,要么不返回任何值。后者将使Firebase中止交易。
要检测事务的最终输出,我发现使用完成回调(而不是Promise)最简单,因为它在一次调用中为您提供了所有参数:
seatsCountRef.transaction((current)=>{
if (current >= details.seatsCount) {
return value - details.seatsCount;
}
}, function(error, committed, snapshot) {
if (error) {
console.log('Transaction failed abnormally!', error);
} else if (!committed) {
console.log('We aborted the transaction, because there are not enough seats.');
} else {
console.log('Seat count updated');
}
})
第一个错误情况的最常见原因是必须过于频繁地重试该交易,这意味着太多用户试图同时要求获得席位。一种典型的解决方案是放弃,即让客户端稍后重试。