首页 > 解决方案 > 在 .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;
        });

标签: javascriptasynchronouspromisenested

解决方案


您正在使用列表或承诺而不是单个承诺,因此请查看使用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;
    });

推荐阅读