AngularFire firestore get / snapshotchanges / valuechanges 对 observable 的操作不是异步的?

AngularFire firestore get / snapshotchanges / valuechanges action on observable is not async?

嗨,我的行为很奇怪。

我正在遍历一些文档并设置一些承诺,即在获取文档时更新 UI。

然而,虽然承诺是原子的,但 firestore / AngularFire 等待所有承诺。

示例:

 for (const event of events) {
        this.eventService.getEventActivitiesAndSomeStreams(this.user,
          event.getID(),
          [DataLatitudeDegrees.type, DataLongitudeDegrees.type])
          .pipe(take(1)).toPromise().then((fullEvent) => {
            this.logger.info(`Promise completed`)
           
          })
      }

人们会期望随着数据的到来,对于每个承诺,它都会慢慢地打印出已完成的承诺。

但是它们都打印一次。看起来这些承诺并不是一一兑现的,而是“一下子”兑现的。在打印第一个控制台日志之前有很长的等待时间,然后所有的承诺都打印出来。

所以我希望如果我有一个进度条增加一点但很少但立即增加

内部调用this.eventService.getEventActivitiesAndSomeStreams

return this.afs
        .collection('users')
        .doc(userID)
        .collection('events')
        .doc(eventID)
        .collection('activities')
        .doc(activityID)
        .collection('streams', ((ref) => {
          return ref.where('type', 'in', typesBatch);
        }))
        .get()
        .pipe(map((documentSnapshots) => {
          return documentSnapshots.docs.reduce((streamArray: StreamInterface[], documentSnapshot) => {
            streamArray.push(this.processStreamDocumentSnapshot(documentSnapshot)); // Does nothing rather to create an class of the JSON object passed back from the firestore
            return streamArray;
          }, []);
        }))

现在,如果我在 for 循环中放置一个 await,这当然可以正常工作并按预期完成承诺,但是这会花费很多时间。

我也试过不用AngularFire,用原生JS SDK效果一样

我怀疑是 IndexedDB 导致了这个或其他一些 Firebase 逻辑。

我在这里遗漏了什么,如果可能的话我怎样才能得到想要的行为?

您可以通过 ["users" -> "events" -> "something"] firestore collections 重现这个,假设每个“user”有 500 个“events”并且每个事件都有 2 个文档.

因此获取用户的所有事件,并尝试为每个事件做出承诺,该承诺将 return 2 个“某物”文档放入 for 数组)

这种行为是意料之中的,与 firebase 毫无关系。您正在遍历数组并发送请求。项目之间没有等待或延迟,因此 for 循环(没有 await 语句)将在极短的时间内完成,这意味着所有请求都在彼此之间的毫秒内发送,或者基本上是同时发送.所以他们的回复应该也基本同时到达。

您已经声明您不想使用 await 语句并逐个迭代,因此很难确切地知道您想要或期望发生什么。也许您希望它们间隔 0.5 秒?如果是这样,您需要编写该逻辑:

timer(0, 500).pipe( // put whatever ms time between requests you want here?
  take(events.length),
  switchMap(i => {
    return this.eventService.getEventActivitiesAndSomeStreams(this.user,
      events[i].getID(),
      [DataLatitudeDegrees.type, DataLongitudeDegrees.type]).pipe(take(1))
  })
).subscribe(fullEvent => {
  this.logger.info(`Promise completed`)
})

(删除的 promises 导致 idk 为什么首先使用它们,这种控制在 rxjs IMO 中更容易)