Javascript HTML:如何在执行函数之前获得计算结果
我有一个脚本,我正试图执行。我需要脚本,在按下提交按钮时:Javascript HTML:如何在执行函数之前获得计算结果,javascript,html,google-cloud-firestore,Javascript,Html,Google Cloud Firestore,我有一个脚本,我正试图执行。我需要脚本,在按下提交按钮时: 从Google firestore获取值 在计算中使用这些值 使用此计算的结果写回firestore数据库 我将console.log(“eff[1,2,3]”+计算结果)放在控制台日志中,以帮助跟踪执行顺序。它首先显示eff3,然后显示eff1,然后显示eff2,这意味着提交给firestore的值为零(与计算前一样)。计算会计算正确答案,但不会将答案提交给数据库 如何更改代码以使其按正确的顺序执行 // Triggered when
console.log(“eff[1,2,3]”+计算结果)
放在控制台日志中,以帮助跟踪执行顺序。它首先显示eff3
,然后显示eff1
,然后显示eff2
,这意味着提交给firestore的值为零(与计算前一样)。计算会计算正确答案,但不会将答案提交给数据库
如何更改代码以使其按正确的顺序执行
// Triggered when the send new message form is submitted.
function onMessageFormSubmit(e) {
e.preventDefault();
//Calculate efficiency
var preodo = 0
var efficiency = 0
firebase.firestore().collection('Vehicle').doc(reg.value).collection('Refuels').orderBy('Date', 'desc').limit(1)
.onSnapshot(function(snapshot) {
snapshot.docChanges().forEach(function(change) {
preodo = change.doc.data().Odometer
efficiency = (odo.value - preodo) / amount.value
efficiency = efficiency.toFixed(4);
console.log("eff1:" + efficiency)
});
console.log("eff2:" + efficiency)
});
//Save refuel transaction with all details form the form as well as the calculated efficiency
console.log("eff3:" + efficiency)
saveMessage(reg.value, odo.value, date.value, amount.value, price.value, rebate.value, efficiency).then(function() {
window.alert('Refuel submitted!')
// Clear message text field and re-enable the SEND button.
resetMaterialTextfield();
toggleButton();
});
}
通过使用@Professor Abronsius的建议,我把我的代码放在了一个
承诺中
//提交发送新邮件表单时触发。
函数onMessageFormSubmit(e){
e、 预防默认值();
让我承诺=新承诺(函数(myResolve,myReject){
//计算效率
var preodo=0
var效率=0
firebase.firestore().collection('Vehicle').doc(reg.value.).collection('refells').orderBy('Date','desc').limit(1)
.onSnapshot(功能(快照){
snapshot.docChanges().forEach(函数(更改){
preodo=change.doc.data().里程表
效率=(odo.value-preodo)/amount.value
效率=效率。toFixed(4);
console.log(“eff1:+效率)
});
console.log(“eff2:+效率)
myResolve(效率);//成功时
myReject(“无法计算效率”);//出错时
});
});
//“消费代码”(必须等待承诺兑现)
我的承诺,那么(
职能(效率){
//保存加油事务,包括表单中的所有详细信息以及计算的效率
console.log(“eff3:+效率)
saveMessage(reg.value、odo.value、date.value、amount.value、price.value、retriep.value、efficiency){
window.alert('加油已提交!')
//清除消息文本字段并重新启用发送按钮。
resetMaterialTextfield();
切换按钮();
});
},
函数(错误){
window.alert(错误)
}
);
}
通过使用@Professor Abronsius的建议,我把我的代码放在了一个承诺中
//提交发送新邮件表单时触发。
函数onMessageFormSubmit(e){
e、 预防默认值();
让我承诺=新承诺(函数(myResolve,myReject){
//计算效率
var preodo=0
var效率=0
firebase.firestore().collection('Vehicle').doc(reg.value.).collection('refells').orderBy('Date','desc').limit(1)
.onSnapshot(功能(快照){
snapshot.docChanges().forEach(函数(更改){
preodo=change.doc.data().里程表
效率=(odo.value-preodo)/amount.value
效率=效率。toFixed(4);
console.log(“eff1:+效率)
});
console.log(“eff2:+效率)
myResolve(效率);//成功时
myReject(“无法计算效率”);//出错时
});
});
//“消费代码”(必须等待承诺兑现)
我的承诺,那么(
职能(效率){
//保存加油事务,包括表单中的所有详细信息以及计算的效率
console.log(“eff3:+效率)
saveMessage(reg.value、odo.value、date.value、amount.value、price.value、retriep.value、efficiency){
window.alert('加油已提交!')
//清除消息文本字段并重新启用发送按钮。
resetMaterialTextfield();
切换按钮();
});
},
函数(错误){
window.alert(错误)
}
);
}
Firestore操作是异步的,因此您需要承诺处理它们。完全按照使用saveMessage()
所做的操作,但返回一个值
另外,请使用.get()
而不是.onSnapshot()
,因为后者将继续侦听对引用文档所做的更改,您不需要这些更改,因为您在单击按钮时执行此操作
function get_efficiency(regValue) {
efficiency = -1
// return a Promise which will return the efficiency after all computations are done
return firebase.firestore().collection('Vehicle')
.doc(reg.value)
.collection('Refuels')
.orderBy('Date', 'desc')
.limit(1)
.get()
.then(function (querySnapshots) { // this will execute after all documents are fetched from the db
querySnapshots.forEach(function(doc) {
preodo = doc.data().Odometer
efficiency = (odo.value - preodo) / amount.value
efficiency = efficiency.toFixed(4);
console.log("eff1:" + efficiency)
});
console.log("eff2:" + efficiency)
return efficiency
})
}
// Triggered when the send new message form is submitted.
function onMessageFormSubmit(e) {
e.preventDefault();
//Calculate efficiency
var preodo = 0
var efficiency = 0
get_efficiency(reg.value)
.then(function (efficiency) { // this will execute after you computed the efficiency
// efficiency param is the one returned from the PROMISE from get_efficiency()
//Save refuel transaction with all details form the form as well as the calculated efficiency
console.log("eff3:" + efficiency)
saveMessage(reg.value, odo.value, date.value, amount.value, price.value, rebate.value, efficiency).then(function() {
window.alert('Refuel submitted!')
// Clear message text field and re-enable the SEND button.
resetMaterialTextfield();
toggleButton();
});
})
}
Firestore操作是异步的,因此您需要承诺处理它们。完全按照使用
saveMessage()
所做的操作,但返回一个值
另外,请使用.get()
而不是.onSnapshot()
,因为后者将继续侦听对引用文档所做的更改,您不需要这些更改,因为您在单击按钮时执行此操作
function get_efficiency(regValue) {
efficiency = -1
// return a Promise which will return the efficiency after all computations are done
return firebase.firestore().collection('Vehicle')
.doc(reg.value)
.collection('Refuels')
.orderBy('Date', 'desc')
.limit(1)
.get()
.then(function (querySnapshots) { // this will execute after all documents are fetched from the db
querySnapshots.forEach(function(doc) {
preodo = doc.data().Odometer
efficiency = (odo.value - preodo) / amount.value
efficiency = efficiency.toFixed(4);
console.log("eff1:" + efficiency)
});
console.log("eff2:" + efficiency)
return efficiency
})
}
// Triggered when the send new message form is submitted.
function onMessageFormSubmit(e) {
e.preventDefault();
//Calculate efficiency
var preodo = 0
var efficiency = 0
get_efficiency(reg.value)
.then(function (efficiency) { // this will execute after you computed the efficiency
// efficiency param is the one returned from the PROMISE from get_efficiency()
//Save refuel transaction with all details form the form as well as the calculated efficiency
console.log("eff3:" + efficiency)
saveMessage(reg.value, odo.value, date.value, amount.value, price.value, rebate.value, efficiency).then(function() {
window.alert('Refuel submitted!')
// Clear message text field and re-enable the SEND button.
resetMaterialTextfield();
toggleButton();
});
})
}
我的猜测是,从未使用过Google Firestore的
onsnapshot
方法是异步的,但是您的代码以同步方式运行savemessage
方法。您是否可以将Promise
添加到onSnapshot
方法中,并使用解析的值继续程序流程?您是否可以将saveMessage
code向上移动到“eff2”行之后?@carljdp,如果我这样做,它会多次提交保存,就像它在loop@JillianWittstock,我明白了。在进一步调试时,我还没有更多的建议。我猜,从未使用过Google Firestore的情况下,onsnapshot
方法是异步的,但是您的代码以同步方式运行savemessage
方法。您是否可以将Promise
添加到onSnapshot
方法中,并使用解析的值继续程序流程?您是否可以将saveMessage
code向上移动到“eff2”行之后?@carljdp,如果我这样做,它会多次提交保存,就像它在loop@JillianWittstock,我明白了。在进一步的调试中,我还没有更多的建议。它似乎对数据库中的每个条目都重复循环,所以seco