【问题标题】:Tasked called first after finishing the task before完成之前的任务后先调用tasked
【发布时间】:2019-01-16 20:42:55
【问题描述】:

我想填充一个 HTML sn-p(你可以在下面看到它)。所以我想实现这一点:https://www.dropbox.com/s/941jes7svcyusmf/example.PNG?dl=0 所以我写了这个 js 代码(注意:我使用 firebase)来填充 div 并填写值:

members.forEach(el => {
              console.log(el)

              table_number++;
              console.log("forEachMember" + table_number);

              const html = populateTable("member_name" + table_number, "layout_table" + table_number);
              document.getElementById("main_padding").insertAdjacentHTML('beforeend', html);

              db.collection("users").doc(el).collection("grades").get().then(function(querySnapshot) {
                querySnapshot.forEach(function(doc) {
                    console.log(doc.id, " => ", doc.data());
                    const data = doc.data();

                    addToTable("grade_table" + table_number, doc.id, data.mdl, data.klu);

                });
              });
            })  

这是我将值添加到表中的函数:

function addToTable(table_name, subject, mdl, klu) {

  var subject_name = getSubjectByNumber(subject);
  var short_subject = getSubjectShortByNumber(subject);

      //Zeile erstellen

      console.log("addToTable" + table_name);

      var y = document.createElement([short_subject]);
      y.setAttribute("id", [short_subject]);
      document.getElementById([table_name]).appendChild(y);

      //Spalten in einer Zeile

      var y = document.createElement("TR");
      y.setAttribute("id", [short_subject]);

      //Spalten in einer Zeile

      var cE = document.createElement("TD");
      var tE = document.createTextNode([subject_name]);
      cE.appendChild(tE);
      y.appendChild(cE);

      var a = document.createElement("TD");
      var b = document.createTextNode([mdl]);
      a.appendChild(b);
      y.appendChild(a);

      var c = document.createElement("TD");
      var d = document.createTextNode([klu]);
      c.appendChild(d);
      y.appendChild(c);


      document.getElementById(table_name).appendChild(y);
}  

但我的问题是只有表格但没有填充行和列。 (信息不足)所以我得到这个错误:Uncaught (in promise) TypeError: Cannot read property 'appendChild' of null。所以桌子在那里,但找不到它。所以我开始使用 console.log();似乎members.forEach(el => { 任务运行完成,然后db.collection("users").doc(el).collection("grades").get().then(function(querySnapshot) { 任务首先启动。并且 var table_number 为空。但是为什么以及如何解决这个问题?

编辑:
@israelss 提到这是 Firebase 的异步任务的问题。但是如何解决呢?

【问题讨论】:

    标签: javascript html firebase google-cloud-firestore


    【解决方案1】:

    好吧,由于 JavaScript 是异步的,循环不会等待 mongo 查询开始,因此,您必须首先运行 mongo 查询并在其 promise 中执行循环。 我在用手机,所以输入代码有点烦人,但我很确定这是问题所在

    【讨论】:

    • 当您回到笔记本电脑时,能给我一个代码示例吗?因为如何解决这个问题会很有趣。 :)
    • 它不允许我将其添加为评论,所以我添加了一个新答案
    【解决方案2】:

    应该是这样的:

    db.collection("users").doc(el).collection("grades").get().then(function(querySnapshot) {
            querySnapshot.forEach(function(doc) {
                console.log(doc.id, " => ", doc.data());
                const data = doc.data();
                members.forEach(el => {
                    console.log(el)
    
                    table_number++;
                    console.log("forEachMember" + table_number);
    
                    const html = populateTable("member_name" + table_number, "layout_table" + table_number);
                    document.getElementById("main_padding").insertAdjacentHTML('beforeend', html);
                    addToTable("grade_table" + table_number, doc.id, data.mdl, data.klu);
    
                  })  
            });
          });
    

    问题是首先你必须做最耗时的任务,在这种情况下是数据库查询,然后做剩下的。 由于 Javascript 是异步的,这意味着它不会等待一条指令完成后再继续执行下一条指令,它会尝试同时执行所有指令,除非您使用 Promise。

    【讨论】:

    • 您好,很抱歉我的回复晚了。但这正是线索。在代码的第一行:db.collection("users").doc(el).collection("grades").get().then(function(querySnapshot) {。 “el”未定义。因为我用这一行初始化了“el”,这行在后面首先出现:members.forEach(el => {
    • 希望你能帮助我,即使回复晚了
    猜你喜欢
    • 2020-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多