我敢肯定,我在这里很困惑,因此请给予任何帮助。
这是我的情况:
我从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的工作还不够长。
最后我要实现的是:
获取文档。映射并处理它,但是在过程中,我需要兑现承诺。
我不想将那个诺言退还给呼叫者。
这有意义吗?
还是我构造出了完全错误的结构?
答案 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)
这是mergeMap
或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
之类的运算符以相同的方式处理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);