关于诺言,我是一个初学者,我正试图了解如何使用它们。
我有一个Firebase触发器,正在执行一些验证。如果验证失败,我想“退出”触发器,这意味着验证后我不想执行任何代码(假设验证失败)。但是确实如此。即使我确定验证失败(“由于不活动,您已超时。请返回床单预订地图并重新开始”已发送至我正在开发的android应用),之后的代码仍会保留执行。我知道这是因为我已经在其中放置了控制台日志。
我已经在我的代码中添加了注释,以用于我正在谈论的验证以及不希望执行的代码。
exports.createCharge = functions.database.ref('/customers/{userId}/charges/{id}')
.onCreate((snap, context) => {
console.log("Entered createharge function");
const val = snap.val();
return admin.database().ref(`/customers/${context.params.userId}/customer_id`)
.once('value').then((snapshot) => {
return snapshot.val();
}).then((customer) => {
// Do stuff
if (val.type === 'beds') {
// Check if user email is the same as bed email
for (var i = 0; i < val.beds.length; i++) {
var bedEmailRef = db.ref(`beds/${val.hid}/${val.beds[i]}/email`);
bedEmailRef.on("value", function(bedEmailSnap) {
var bedEmail = bedEmailSnap.val();
if (val.email !== bedEmail) { // VALIDATION
snap.ref.child('error').set("You have been timed out due to inactivity. Please go back to the bed booking map and start again");
return null; // Here, I want to exit the whole function.
}
});
}
// If val.email !== bedEmail, I NEVER want to reach here!
return admin.database().ref(`/hotels/${val.hid}/bedPrice`)
.once('value').then((tempBedPrice) => {
// do stuff
console.log("got here");
return stripe.charges.create(charge, {idempotency_key: idempotencyKey});
}).then((response) => {
// Do more stuff
return snap.ref.set(response);
}).catch((error) => {
snap.ref.child('error').set(userFacingMessage(error));
return reportError(error, {user: context.params.userId});
})
} else throw Error('No type');
});
});
为什么我会得到这种行为?验证执行后如何停止代码?
答案 0 :(得分:0)
问题是您要在检查“床”类型后添加“侦听器”。一种解决方案是fetch data once:
// This is a snippet from Firebase documentation
return firebase.database().ref('/users/' +
userId).once('value').then(function(snapshot) {
var username = (snapshot.val() && snapshot.val().username) ||
'Anonymous';
// ...
});
或重构代码,以便您的验证可以设置为满足某些条件时可以返回的回调。
另外,这里有一个link for Cloud functions best practices,可以帮助您编写更好的云功能。
答案 1 :(得分:0)
如果您要退出/不想再在监听器上发生任何事件,请按如下所示重构代码:
bedEmailRef.on("value", function(bedEmailSnap) {
var bedEmail = bedEmailSnap.val();
if (val.email !== bedEmail) { // VALIDATION
snap.ref.child('error').set("You have been timed out due to inactivity. Please go back to the bed booking map and start again");
bedEmailRef.off('value'); // This will stop listening for further events
return null; // This is useless because returning inside a listener has no effect
}
});