首页 > 解决方案 > 如何在管道地图中处理承诺

问题描述

我肯定我在这里很困惑,所以请提供任何帮助。

这是我的场景:

我从 Firestore 中提取了一个文档:

return this.afs.collection("events").doc(eventID).snapshotChanges().pipe(
      map( document => {

      })
    );

到这里为止一切都很好。

但在地图内我需要一个承诺来解决(或不解决)

例如:

return this.afs.collection("events").doc(eventID).snapshotChanges().pipe(
      map( document => {
        // This is a promise the below part 
        const data = await EventImporterJSON.getFromJSON(document.payload.data())
        return data
      })
    );

我知道await那里不可能发生。我很困惑如何解决这个问题,也许我在 observables 和 rxjs 上工作的时间不够长。

最后我想要实现的是:

获取文档。映射并处理它,但在这个过程中,我需要处理一个承诺。

不过,我不想将该承诺返回给调用者。

这有意义吗?

还是我的结构完全错误?

标签: javascriptrxjsgoogle-cloud-firestoreobservable

解决方案


这是mergeMapor的典型用例concatMap

return this.afs.collection("events").doc(eventID).snapshotChanges().pipe(
  mergeMap(document => {
    // This is a promise the below part 
    return EventImporterJSON.getFromJSON(document.payload.data())
  })
);

但是,您也可以使用async - await,因为mergeMap处理 Observables、Promises、数组等操作符的方式相同,因此您只需在mergeMap项目函数中返回一个 Promise,它就可以正常工作。

通常,您不需要await在单个方法中使用多个 s,因为更“Rx”的做事方式是链接运算符,但如果您愿意,您可以因为async方法返回一个 Promise,而 RxJS 将像处理任何其他 Promise 一样处理它。

const delayedPromise = () => new Promise(resolve => {
  setTimeout(() => resolve(), 1000);
})

of('a').pipe(
  mergeMap(async v => {
    console.log(1);
    await delayedPromise();
    console.log(2);
    await delayedPromise();
    console.log(3);
    await delayedPromise();
    return v;
  })
).subscribe(console.log);
// 1
// 2
// 3
// a

Live demo: https://stackblitz.com/edit/rxjs-3fujcs

推荐阅读