HTML:如何在执行函数之前获取计算结果

时间:2021-02-16 07:01:41

标签: javascript html google-cloud-firestore

我有一个要执行的脚本。我需要脚本,按下提交按钮:

  1. 从 Google Firestore 获取值
  2. 在计算中使用这些值
  3. 使用此计算的结果写回 firestore 数据库

我已经放置了 console.log("eff[1,2,3]" + result of calculation) 来帮助在控制台日志中跟踪执行顺序。它首先显示 eff3 然后 eff1 然后 eff2 所以这意味着提交给 firestore 的值为零(就像在计算之前一样)计算确实计算出正确的答案,只是没有t 将答案提交给数据库。

如何更改我的代码以使其以正确的顺序执行?

// 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();
  });
}

2 个答案:

答案 0 :(得分:2)

Firestore 操作是异步的,因此您需要使用 promise 来处理它们。完全按照您对 <input type="text" name="username" placeholder="username" required> 所做的操作,但要返回一个值

另外,使用 saveMessage() 而不是 .get(),因为后者会继续监听对引用文档所做的更改,您不需要,因为您在单击按钮时执行此操作.

.onSnapshot()

答案 1 :(得分:0)

通过使用@Professor Abronsius 的建议,我将我的代码放入 Promise

// Triggered when the send new message form is submitted.
function onMessageFormSubmit(e) {
  e.preventDefault();
  let myPromise = new Promise(function(myResolve, myReject) {
    //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)
        myResolve(efficiency); // when successful
        myReject("Not able to calculate efficiency"); // when error
      });
  });

  // "Consuming Code" (Must wait for a fulfilled Promise)
  myPromise.then(
    function(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();
      });
    },
    function(error) {
      window.alert(error)
    }
  );
}

这有效...它只提交到 firestore 一次但是...它打印到控制台日志如下: eff1eff2eff3eff1eff1eff2

我现在很好奇为什么它会重复?重复这个并不重要,因为它不会影响数据库或用户界面,但我很好奇。

相关问题