如何处理管道地图内的承诺

Jim*_*ane 18 javascript observable rxjs google-cloud-firestore

我绝对确定我在这里感到困惑,所以请感谢任何帮助。

这是我的场景:

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

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

      })
    );
Run Code Online (Sandbox Code Playgroud)

到这里一切都很好。

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

例如:

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
      })
    );
Run Code Online (Sandbox Code Playgroud)

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

最后我想要实现的是:

获取文档。映射并处理它,但在流程内部,我需要处理一个承诺。

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

这有意义吗?

还是我的结构完全错误?

mar*_*tin 23

这是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())
  })
);
Run Code Online (Sandbox Code Playgroud)

但是,您也可以使用async - await,因为诸如mergeMap处理 Observables、Promises、数组等的操作符以相同的方式处理,因此您可以只在mergeMaps 项目函数中返回一个 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
Run Code Online (Sandbox Code Playgroud)


Kev*_*CHT 7

Observables 可以被看作是 promises 的一层,你为什么不这样使用你的 promise 呢?像这样 :

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
});
Run Code Online (Sandbox Code Playgroud)

1 用 map 传送你的第一个 observable 只是为了简化你的返回值

2 switchMap 到另一个 observable,这将是你作为 Observable 的承诺(使用“from”运算符);

map 操作符是为了以同步和“纯粹”的方式改进结果,比如只返回对象的几个属性或过滤数据,在这里你想链接两个异步操作,所以我建议你保持它在 rx 方法中