在.then函数中返回嵌套在forEach中的promise

时间:2019-12-09 16:17:21

标签: javascript asynchronous promise nested

我正努力返回嵌套在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;
        });

2 个答案:

答案 0 :(得分:3)

您正在使用列表或承诺而不是单个承诺,因此请看一下使用 @FindBy(id = "macro-param-graph") private WebElement graphIdXml; public void invokeGraphXmlPayload(String payload) throws IOException, InterruptedException { String myGraph = generateStringFromResource("src/test/resources/testDataResources/" + payload); WebDriverWait wait = new WebDriverWait(driver, 15); wait.until(ExpectedConditions.visibilityOf(graphIdXml)); graphIdXml.sendKeys(myGraph); btn_Preview.click(); } 而不是(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all)。

Promise.all()方法返回一个Promise,当作为可迭代对象传递的所有诺言都已兑现或可迭代对象不包含任何诺言时,该Promise就会实现。它拒绝的原因是第一个承诺被拒绝。

Promise.all

答案 1 :(得分:2)

您没有真正指定诺言的哪一部分-this.topics.pushthis.$fireStore...get()

我将假设后者。

您想要做的更多是这样的:

.then(snapshot => {
        var promises = snapshot.map(sec => {
          return this.$fireStore.
                       ...
                       .get()
          });
        return Promise.all(promises);
 });

当您执行.map并在回调中返回一个promise时,您将做出一个promise数组。将Promise.all放在一组诺言中会将它们合并为一个诺言。