如何在js中从firebase加载数据后调用另一个函数?

时间:2018-04-20 07:11:35

标签: javascript html firebase firebase-realtime-database

下面是代码在重定向到下载页面时自动生成pdf。我使用jsPDF lib生成pdf文件。问题是从firebase加载数据需要时间,因为pdf正在生成空值。我需要在从firebase加载数据后调用pdf生成函数。这样pdf文件就会生成值。

以下是代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
</head>

<style>
    .temp_log{
        margin-left: 100px;
        position: absolute;
        bottom: 19px;
    }    


th, td {
    text-align: left;
    padding: 8px;
}

tr:nth-child(even){background-color: #f2f2f2}

th {
    background-color: #4CAF50;
    color: white;
}
</style>

<body>
    <button onclick="genPDF()">Generate</button>
      <ul>
          <li>
            <div class ="patient-details">
              <h1 >Patient Details</h1>
              <img src="assets/img/boy.png" alt="image not found">
              <div>
             <h4>Patient Name: John Son</h4>
             <h4>Age: 24</h4>
             <h4>Blood Group: A+</h4>
             <h4>Phone No: +91-7310778879</h4>
             </div>
            </div>
          </li>
    </ul>



   <table border="1">
           <tr>
             <th>Pluse</th>
            </tr>
        <th id="hearbeat_prev"></th>
    </table>


      <table border="1" class="temp_log">
           <tr>
             <th>Temp</th>
            </tr>
        <th id="temp_prev"></th>
    </table>

</body> 
<script src="https://www.gstatic.com/firebasejs/4.10.1/firebase.js"></script>
<script> 
  var config = {
    apiKey: "**************",
    authDomain: "********",
    databaseURL: "********",
    projectId: "*******",
    storageBucket: "********",
    messagingSenderId: "*******"
  };
  firebase.initializeApp(config);
</script>








<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>


<script src="assets/js/jspdf.debug.js"></script>
<script src="assets/js/html2pdf.js"></script>


<script>

    heartbeat_previous_data();
    temperature_prev_data();
function temperature_prev_data()
{
    var data ="data: "
    console.log("inside temp 10");

    var rootRef = firebase.database().ref("temp");
     rootRef.limitToLast(10).on('child_added', function(snap)
          {
        var temp = snap.child("fahrenheit").val();
         console.log(temp);
         document.getElementById("temp_prev").innerHTML += temp +" F" +"<br>";



     });

}


function heartbeat_previous_data()
{
     var rootRef = firebase.database().ref("pulse");  

    var data = "data: ";
    var valid = false;
    var test = 0 ;

    rootRef.limitToLast(10).on('child_added', function(snap) {


    var heart = snap.child("rate").val();
         console.log(heart);


        document.getElementById("hearbeat_prev").innerHTML += heart +" "+ "BPM"+ "<br>";



    });

}
    </script>
<script>



        var pdf = new jsPDF('p', 'pt', 'letter');
        var canvas = pdf.canvas;
        canvas.height = 72 * 11;
        canvas.width=72 * 8.5;;
        // var width = 400;
        html2pdf(document.body, pdf, function(pdf) {
                var iframe = document.createElement('iframe');
                iframe.setAttribute('style','position:absolute;right:0; top:0; bottom:0; height:100%; width:500px');
                document.body.appendChild(iframe);
                iframe.src = pdf.output('datauristring');
            }
        );


    </script>
</html>

2 个答案:

答案 0 :(得分:0)

一种解决方案是创建超时并在每次在DOM中附加内容时重置它,并且当数据追加完成时,它将运行与pdf相关的函数。请参阅以下更新代码:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
</head>

<style>
  .temp_log {
    margin-left: 100px;
    position: absolute;
    bottom: 19px;
  }

  th,
  td {
    text-align: left;
    padding: 8px;
  }

  tr:nth-child(even) {
    background-color: #f2f2f2
  }

  th {
    background-color: #4CAF50;
    color: white;
  }
</style>

<body>
  <button onclick="genPDF()">Generate</button>
  <ul>
    <li>
      <div class="patient-details">
        <h1>Patient Details</h1>
        <img src="assets/img/boy.png" alt="image not found">
        <div>
          <h4>Patient Name: John Son</h4>
          <h4>Age: 24</h4>
          <h4>Blood Group: A+</h4>
          <h4>Phone No: +91-7310778879</h4>
        </div>
      </div>
    </li>
  </ul>



  <table border="1">
    <tr>
      <th>Pluse</th>
    </tr>
    <th id="hearbeat_prev"></th>
  </table>


  <table border="1" class="temp_log">
    <tr>
      <th>Temp</th>
    </tr>
    <th id="temp_prev"></th>
  </table>

</body>
<script src="https://www.gstatic.com/firebasejs/4.10.1/firebase.js"></script>
<script>
  var config = {
    apiKey: "**************",
    authDomain: "********",
    databaseURL: "********",
    projectId: "*******",
    storageBucket: "********",
    messagingSenderId: "*******"
  };
  firebase.initializeApp(config);
</script>








<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>


<script src="assets/js/jspdf.debug.js"></script>
<script src="assets/js/html2pdf.js"></script>


<script>
  heartbeat_previous_data();
  temperature_prev_data();

  var waitTimeout = null

  function checkDone() {
    clearTimeout(waitTimeout)
    waitTimeout = setTimeout(function() {
      var pdf = new jsPDF('p', 'pt', 'letter');
      var canvas = pdf.canvas;
      canvas.height = 72 * 11;
      canvas.width = 72 * 8.5;;
      // var width = 400;
      html2pdf(document.body, pdf, function(pdf) {
        var iframe = document.createElement('iframe');
        iframe.setAttribute('style', 'position:absolute;right:0; top:0; bottom:0; height:100%; width:500px');
        document.body.appendChild(iframe);
        iframe.src = pdf.output('datauristring');
      });
    }, 300)
  }

  function temperature_prev_data() {
    var data = "data: "
    console.log("inside temp 10");

    var rootRef = firebase.database().ref("temp");
    rootRef.limitToLast(10).on('child_added', function(snap) {
      var temp = snap.child("fahrenheit").val();
      console.log(temp);
      document.getElementById("temp_prev").innerHTML += temp + " F" + "<br>";
      checkDone()
    });
  }


  function heartbeat_previous_data() {
    var rootRef = firebase.database().ref("pulse");

    var data = "data: ";
    var valid = false;
    var test = 0;

    rootRef.limitToLast(10).on('child_added', function(snap) {

      var heart = snap.child("rate").val();
      console.log(heart);

      document.getElementById("hearbeat_prev").innerHTML += heart + " " + "BPM" + "<br>";
      checkDone()
    });
  }
</script>

</html>

答案 1 :(得分:0)

对Firebase数据库的调用是异步的,因为您显然并行触发不同的调用,所以应该等待所有这些不同的调用完成以便开始生成PDF。

每次调用都会返回一个promise,因此你必须使用Promise.all()方法(参见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all)来实现这种模式。

您能否显示有关genPDF功能的更多信息?

编辑:

1 /转换调用Firebase的两个函数,使它们返回Promise

function temperature_prev_data() {
....
var rootRef = firebase.database().ref("temp");
return rootRef.limitToLast(10).on('child_added', function(snap) {   //note the return
    var temp = snap.child("fahrenheit").val();
     console.log(temp);
     document.getElementById("temp_prev").innerHTML += temp +" F" +"<br>";
 });
}

function heartbeat_previous_data() {
 ....
  return rootRef.limitToLast(10).on('child_added', function(snap) {
   ....
  });
}

2 /将两个Promises添加到数组中,然后调用Promises.all

function generatePDF() {
    var promises = [];
    promises.push(temperature_prev_data());
    promises.push(heartbeat_previous_data());
    return Promise.all(promises);
})

3 /调用此函数,解决后调用PDF生成

generatePDF()
.then(function() { 
    //generate your PDF here, since all the calls to Firebase have returned data
})
.catch(....);