У меня есть этот простой и короткий код JavaScript для веб-сайта:
db.collection("classes").doc(data.readGrades).get().then(function(doc) {
if (doc.exists) {
const data = doc.data();
const members = data.members;
members.forEach(el => {
db.collection("users").doc(el).collection("grades").get().then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
const data = doc.data();
//some stuff
});
});
})
} else {
console.log("No such document!");
}
}).catch(function(error) {
console.log("Error getting document:", error);
});
Как видите, мне нужно запустить две задачи Firebase Firestore. Важно, чтобы сначала это выполнялось db.collection("classes").doc(data.readGrades).get().then(function(doc) {
, и для каждого из членов эта задача следует за db.collection("users").doc(el).collection("grades").get().then(function(querySnapshot) {
(ПРИМЕЧАНИЕ. Вторая задача требует первого из-за переменной el
). Поэтому моя проблема в том, что я должен дождаться завершения второго задания, прежде чем цикл для следующего члена может продолжаться.
И это точно мой вопрос: как выполнить второе задание перед запуском цикла для следующего члена?
EDIT:
Я изменил свой код Javascript следующим образом:
db.collection("classes").doc(data.readGrades).get().then(function(doc) {
if (doc.exists) {
const data = doc.data();
const members = data.members;
members.reduce((chain, el) => {
table_number++;
const html = fillTemplate("grade_table" + table_number, member_name);
document.getElementById("main_padding").insertAdjacentHTML('beforeend', html);
return chain.then(() =>
db.collection("users").doc(el).collection("grades").get().then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
const data = doc.data();
addToTable("grade_table" + table_number, doc.id, data.mdl, data.klu);
});
})
)
}, Promise.resolve());
} else {
console.log("No such document!");
}
}).catch(function(error) {
console.log("Error getting document:", error);
});
function fillTemplate(table_name, id) {
console.log("ID OF TABLES " + table_name);
return `
<div class="noten_tabelle_permission" id="noten_tabelle_permission">
<h1 id="member_name">${id}</h1>
<table id="${table_name}" style="width:100%">
<tr>
<th>Fach</th>
<th>mündlich</th>
<th>Klausur</th>
</tr>
<!-- Make content with js code -->
</table>
</div>
`;
}
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);
}
Так что обещание работает. Но теперь у меня проблема в том, что обещание работает неправильно. Как видите, я хочу запустить задачу Firestore (Database) для каждого участника. Так что обещание должно уволить каждого нового члена. Но обещание сработает первым в конце.
Базовые знания: я получаю членов из ArrayList из базы данных, и для каждого отдельного члена мне нужно получить конкретные значения на основе этого члена. Когда значения для члена загружены, я добавляю их в таблицу, которая заполняется для каждого члена (как вы можете видеть) в предыдущей задаче. Как я уже сказал, обещание сработает в конце. Таким образом, значения не будут добавлены в конкретную таблицу члена. Они будут добавлены в последнюю таблицу.
РЕДАКТИРОВАТЬ 2 :
Это отредактированный код:
members.reduce((chain, el) => {
db.collection("users").doc(el).collection("user_data").doc("u").get().then(function (doc) {
const data = doc.data();
var member_name = data.name;
table_number++;
const html = fillTemplate("grade_table" + table_number, member_name);
document.getElementById("main_padding").insertAdjacentHTML('beforeend', html);
})
return chain.then(((table_num) => {
return db.collection("users").doc(el).collection("grades").get().then(function (querySnapshot) {
querySnapshot.forEach(function (doc) {
const data = doc.data();
addToTable("grade_table" + table_num, doc.id, data.mdl, data.klu);
});
})
}).bind(null, table_number))
}, Promise.resolve());
Итак, проблема в том, что задача, в которой я получаю имя_символа, выполняется асинхронно, а другая часть - нет. Так что я могу выполнить всю задачу только тогда, когда все загружено. Потому что, как вы видите, мне нужно также имя_члена. ТАК, как перекодировать его, чтобы задача запускалась, когда загружается только все (имя участника / оценки).