如何在管道地图中处理承诺

时间:2018-12-06 10:27:37

标签: javascript rxjs google-cloud-firestore observable

我敢肯定,我在这里很困惑,因此请给予任何帮助。

这是我的情况:

我从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的工作还不够长。

最后我要实现的是:

获取文档。映射并处理它,但是在过程中,我需要兑现承诺。

我不想将那个诺言退还给呼叫者。

这有意义吗?

还是我构造出了完全错误的结构?

2 个答案:

答案 0 :(得分:1)

可观察性可以看作是对诺言的一层,为什么不这样使用诺言呢? 像这样:

let getDataFromJson(payloadData){
    return from(EventImporterJSON.getFromJSON(payloadData());
}

return this.afs.collection("events").doc(eventID).snapshotChanges().pipe(
  map(document=>document.payload.data),
  switchMap( payloadData=> getDataFromJson(payloadData)))
.subscribe(result=>{
    //final result
});

使用管道将地图上的第一个可观测对象简化为简化返回值

将2切换到另一个可观察对象,这就是您作为一个可观察对象(使用“ from”运算符)的承诺;

map运算符用于以同步和“纯”方式(例如仅返回对象的少量属性或过滤数据)改善结果,在这里您希望链接两个异步操作,因此建议您将其保持在rx方法中

答案 1 :(得分:1)

这是mergeMapconcatMap的典型用例:

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之类的运算符以相同的方式处理Observable,Promises,数组等,因此您可以在mergeMap中返回Promise的项目功能,它将正常工作。

通常,您不需要在单个方法中使用多个await,因为更“ 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);

实时演示:https://stackblitz.com/edit/rxjs-3fujcs