javascript - 在 .then 函数中返回嵌套在 forEach 中的承诺
问题描述
我正在努力返回嵌套在函数中的承诺(或多个承诺),该forEach
函数嵌套在.then
函数中。
第二个.then
不等待第一个中的承诺.then
完成,因此不返回“this.topics”(而不是空数组)和日志undefined
而不是数据。
我认为最好通过查看代码来绕开你的脑袋,所以这里是:
getTopics() {
this.$fireStore
.collection("courses")
.doc(this.$store.state.courses.currentlyPreviewing.cid)
.collection("sections")
.get()
.then(snapshot => {
snapshot.forEach(sec => {
return this.$fireStore
.collection("courses")
.doc(this.$store.state.courses.currentlyPreviewing.cid)
.collection("sections")
.doc(sec.id)
.collection("topics")
.orderBy("order")
.get()
.then(snapshot => {
snapshot.forEach(doc => {
this.topics.push({
data: doc.data(),
topic_id: doc.id,
sectionOfTopic_id: sec.id
});
});
console.log('First done!') // Only logged after data and this.topics
});
})
})
.then((data) => {
console.log(data) // Logs undefined
console.log(JSON.stringify(this.topics)) // Logs empty array
return this.topReady = true;
});
解决方案
您正在使用列表或承诺而不是单个承诺,因此请查看使用Promise.all
代替(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all)。
Promise.all() 方法返回一个 Promise,当所有作为 iterable 传递的 Promise 都已实现或 iterable 不包含任何 Promise 时,该 Promise 就会实现。它以拒绝的第一个承诺的原因拒绝。
getTopics() {
this.$fireStore
.collection("courses")
.doc(this.$store.state.courses.currentlyPreviewing.cid)
.collection("sections")
.get()
.then(snapshot => {
const promises = snapshot.map(sec => {
return this.$fireStore
.collection("courses")
.doc(this.$store.state.courses.currentlyPreviewing.cid)
.collection("sections")
.doc(sec.id)
.collection("topics")
.orderBy("order")
.get()
.then(snapshot => {
snapshot.forEach(doc => {
this.topics.push({
data: doc.data(),
topic_id: doc.id,
sectionOfTopic_id: sec.id
});
});
console.log('First done!') // Only logged after data and this.topics
});
})
return Promise.all(promises)
})
.then((data) => {
console.log(data) // Logs undefined
console.log(JSON.stringify(this.topics)) // Logs empty array
return this.topReady = true;
});