事务api上处理空值"/>
如何在Firebase事务api上处理空值
我具有一个通过事务减少Firebase实时数据库值上的用户信用的功能。正如Firebase transaction API call current data is null中所建议的,交易当前值偶尔会返回null。
我为null情况作了保护,并返回了0,因此交易功能再次触发,直到获得实际的信用值为止。
function charge(cost, description) {
return new Promise((resolve, reject) => {
const creditRef = db.ref(`credits/${userid}`)
ref.transaction(function(current) {
console.log(`${description} current value: ${current}`)
if (current === null) {
console.log(`${description} returns 0 `)
return 0
}
if (cost > current || current === 0) {
//not enough credits return without committing
console.log(`${description} aborts `)
return
}
//commit the new credit value
console.log(`${description} returns ${current} - ${cost}`)
return current - cost
},
(error, commited, snapshot) => {
if (error) {
reject(error)
}
else {
if (commited) {
//user has enough credits
resolve()
}
else {
//not enough credits
reject('no commit')
}
}
})
}
但是,在两个充电功能被背对背触发的情况下,第二个调用将获得当前值0(可能是第一次充电调用返回的0)。因此,如果用户没有足够的积分,它将过早退出。当两个函数都解析后,最终信用额度将为3,而第二次收费呼叫将被忽略。
// User has 5 credits
charge(3, 'first call').then(() => console.log('first call success')
// transaction function returns 0 since current value is null
charge(2, 'second call').then(() => console.log('second call success')
控制台日志输出:
第一个呼叫当前值:null
第一个电话返回0
第二呼叫当前值:0
第二通电话中止
首次通话的当前值:5
第一个电话返回5-3
首次通话成功
第二次呼叫不提交
因此,当用户有足够的信用额度时,第二次收费电话将无法进行。处理Firebase交易无效值案例的正确方法是什么?
回答如下:如果从数据库中获得null
,则不应进行任何更改。由于获得了null
,因此也返回null
。
所以:
const ref = firebase.database().ref(`59571450`)
function charge(cost, description) {
return new Promise((resolve, reject) => {
ref.transaction(function(current) {
console.log(`${description} current value: ${current}`);
if (current === null) {
console.log(`${description} returns null`)
return null;
}
if (cost > current) {
//not enough credits return without committing
console.log(`${description} aborts `)
return
}
//commit the new credit value
console.log(`${description} returns ${current} - ${cost}`)
return current - cost
},
(error, commited, snapshot) => {
if (error) {
reject(error)
}
else {
if (commited) {
//user has enough credits
resolve()
}
else {
//not enough credits
reject('no commit')
}
}
});
});
}
ref.set(5).then(() => {
charge(3, 'first call').then(() => console.log('first call success'))
charge(2, 'second call').then(() => console.log('second call success'))
})
运行时会给出以下输出:
第一次通话的当前值:空
第一次通话返回null
第二个呼叫当前值:空
第二次呼叫返回null
第一次通话的当前值:5
第一个电话返回5-3
第二通话当前值:2
第二次呼叫返回2-2
首次通话成功
第二次通话成功
有关此代码的有效版本,请参见:https://jsbin/xefebul/1/edit?js,console
更多推荐
如何在Firebase事务api上处理空值
发布评论