任务完成后先调用任务

时间:2019-01-16 20:42:55

标签: javascript html firebase google-cloud-firestore

我想填充一个HTML代码段(您可以在下面看到)。所以我想实现这一目标: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为null。但是为什么以及如何解决这个问题?

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

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

应该是这样的:

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);

              })  
        });
      });

问题是,首先您必须执行最耗时的任务,在这种情况下是db查询,然后执行其余的任务。 由于Javascript是异步的,因此它意味着在继续执行下一条指令之前,它不会等待一条指令完成,除非您使用promises,否则它将尝试同时执行所有指令。