- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个简单而简短的网站 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) {
(注意:第二个任务需要第一个,因为var el
)。所以我的问题是我必须等待完成第二个任务,然后才能继续下一个成员的循环。
这正是我的问题:如何在为下一个成员运行循环之前完成第二个任务?
编辑:
我像这样修改了我的 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);
}
因此 promise 有效。但是现在我遇到了 promise 错误的问题。如您所见,我想为每个成员运行一个 Firestore(Database) 任务。所以 promise 应该解雇每个新成员。但 promise 将在最后首先解雇。
背景知识:我从数据库的 ArrayList 中获取成员,对于每个成员,我需要获取基于该成员的特定值。当加载成员的值时,我将它们添加到一个表中,该表为上一个任务中的每个成员(如您所见)填充。正如我所说, promise 将在最后解雇。 因此不会将值添加到成员的特定表中。它们将被添加到最后一个表中。
编辑 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());
所以这里的问题是我获取 member_name 的任务是异步运行的,而另一部分则不是。所以我只能在加载所有内容时运行整个任务。因为如您所见,我还需要 member_name。那么如何对其进行重新编码,使任务在仅加载所有内容(member_name/grades)时运行。
最佳答案
您可以使用 reduce
而不是 forEach
并将空的 Promise
作为初始值传递,以便按顺序处理成员:
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) => {
return chain.then(() =>
db.collection("users").doc(el).collection("grades").get().then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
const data = doc.data();
//some stuff
});
})
)
}, Promise.resolve());
} else {
console.log("No such document!");
}
}).catch(function(error) {
console.log("Error getting document:", error);
});
更新#1:
考虑到更新后的问题,数据可能被添加到最后一个表中,因为在 promise 解决时所有减少迭代都已完成(因此 table_name
变量保留最后一个表的值迭代)。您可以通过 binding
table_name
值到在 promise 解析上调用的回调来解决它:
members.reduce((chain, el) => {
table_number++;
const html = fillTemplate("grade_table" + table_number, doc.id);
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());
更新#2:为了在单个 reduce 迭代中随后运行多个异步操作,请尝试使用 Promise 的 then
方法将它们链接起来:
members.reduce((chain, el) => {
return chain
.then(() => db.collection("users").doc(el).collection("user_data").doc("u").get())
.then(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 table_number;
})
.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);
});
})
})
}, Promise.resolve());
关于javascript - 在为下一个成员运行循环之前完成任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54366941/
我正在寻找一种使此打印 HTML 代码 fragment 向后兼容旧 Android 版本的简单方法: @TargetApi(Build.VERSION_CODES.KITKAT) private v
我在 GCC 终端 (centos linux) 中为 ATM 项目编译以下 c 和 .h 代码时收到以下错误。请帮忙,因为我是编程新手。 validate_acc.h #ifndef _VALIDA
在写关于 SO 的不同问题的答案时,我制作了这个片段: @import url('https://fonts.googleapis.com/css?family=Shadows+Into+Light'
试图弄清楚我应该如何在 my_div_class 之前放置一个 span 而不是替换所有它。现在它取代了 div,但我不想这样做。我假设它类似于 :before 但不知道如何使用它。 { va
我正在使用选择库 http://github.hubspot.com/select/和 noUiSlider https://refreshless.com/nouislider/ .我面临的问题如下
我是开发新手,独自工作。我正在使用 Xcode 和 git 版本控制。可能我没有适本地组织和做错事,但我通常决定做 promise 只是为了在我破坏一切之前做出安全点。在那一刻,我发现很难恰本地描述我
我想确保在同一个桶和键上读取和写入时,应该更新获取的值,也就是说,应该在对其进行写入操作之后获取它。我怎样才能做到这一点? 我想要的是,如果我更新一个键的值,如果我同时使用不同线程获取值,则更新同一个
我的问题与this有关问题,已经有了答案: yes, there is a happens-before relationship imposed between actionsof the thre
The before and after hook documentation on Relish仅显示 before(:suite) 在 before(:all) 之前调用。 我什么时候应该使用其中
我有 CSV 行,我想在其中检测所有内部双引号,没有文本限定符。这几乎可以正常工作,但我的正则表达式还可以检测双引号后的字符。 CSV 部分: "7580";"Lorem ipsum";"";"Lor
是否可以通过Youtube数据API检查广告是否可以与特定视频一起显示? 我了解contentDetails.licensedContent仅显示视频是否已上传至同一伙伴然后由其声明版权。由于第三者权
考虑一下用漂亮的彩色图表描述的“像素管道” https://developers.google.com/web/fundamentals/performance/rendering/ 我有一个元素(比
之前?
在 MVC3 中,我可以轻松地将 jQuery 脚本标签移动到页面底部“_Layout.vbhtml” 但是,在 ASP.NET MVC3 中,当您使用编辑器模板创建 Controller 时,脚手
悬停时内容被替换,但是当鼠标离开元素时我希望它变回来。我该怎么做? $('.img-wrap').hover(function(){ $(this).find('h4').text('Go
已关闭。这个问题是 not reproducible or was caused by typos 。目前不接受答案。 这个问题是由拼写错误或无法再重现的问题引起的。虽然类似的问题可能是 on-top
已关闭。这个问题是 not reproducible or was caused by typos 。目前不接受答案。 这个问题是由拼写错误或无法再重现的问题引起的。虽然类似的问题可能是 on-top
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 已关闭 9 年前。 有关您编写的代码问题的问题必须在问题本身中描述具体问题 - 并包含有效代码以重现该问题。
版本:qwt 6.0.1我尝试开发频谱的对数缩放。我使用简单的线条来启用缩放plotspectrum->setAxisScaleEngine(QwtPlot::yLeft, new QwtLog10S
我有两个相同的表,I_Subject 和 I_Temp_Subject,我想将 Temp_Subject 表复制到 Subject 表。 I_Temp_Subject 由简单用户使用,I_Subjec
我的印象是第一次绘制发生在触发 DOMContentLoaded 事件之后。特别是,因为我认为为了让第一次绘制发生,需要渲染树,它依赖于 DOM 构造。另外,我知道 DOM 构造完成时会触发 DOMC
我是一名优秀的程序员,十分优秀!