如何从回调中获得管道Observable以同步而非异步执行



我的Angular Component中有一个Observable订阅,它使用路由解析器为视图返回数据,如下所示:

ngOnInit(): void {
console.log("start");
this._activatedRoute.data //this returns an observable after executing an http request to get the data.
.subscribe((x) => {
console.log("in subscribe")
// set component variables based on returned value
}); 
console.log("ngOnInit complete");
});

我在控制台中看到的是以下序列(向我表明可观察的http调用是与ngOnInit代码同步进行的(:

start
in subscribe
ngOnInit complete

到目前为止还不错。

现在,我想将第二个(在系列中执行(管道到该观察者中,该观察者调用google.maps API(使用带有回调的函数(。我做了很多关于如何做到这一点的研究。我做这件事的方法之一如下:

ngOnInit(): void {
console.log("start");
this._activatedRoute.data //this returns an observable after executing an http request to get the data.
.pipe(concatMap((data: { shopShowcase: ShopShowcase }) => this.executeGoogleAPIReturningCallbackAsObservable(data.shopShowcase))
)
.subscribe((x) => {
console.log("in subscribe")
// set component variables based on returned value
}); 
console.log("ngOnInit complete");
});

public executeGoogleAPIReturningCallbackAsObservable(shopShowcase: ShopShowcase): Observable<ShopShowcase> {
console.log("in observable creation")
//code here to define svService and svLocationRequest
return Observable.create((observer) => {
svService.getPanorama(svLocationRequest, (data, status) => {
console.log("in Callback");
let panoId = data.location.pano;
shopShowcase.PanoId = panoId;
observer.next(shopShowcase);
observer.complete();
})
});
}

我尝试了各种方法来从回调中创建可观察对象,但它们都呈现了相同的console.log输出序列,如下所示。请注意,这一次ngOnInit调用正在完成,只有THEN是正在执行的可观察回调。

start
in observable creation
ngOnInit complete
in callback
in subscribe

基于大量的研究,我理解.pipe(concatMap(((会导致管道可观察到的在序列中执行,从而产生这样的输出:

start
in observable creation
in callback
in subscribe
ngOnInit complete

我需要管道回调同步执行,因为我需要在到达ngOnInitComplete时设置组件变量。

请告诉我如何才能做到这一点?

我想你误解了Observable的工作原理(我的意思不是冒犯(。Observable就像异步等待/承诺一样,但适用于多个值。您的";非预期";输出正确。

开始在可观察的创造中ngOnInit完成在回调中订阅

以上输出是正确的,因为Observable是异步工作的。如果你想在observable subscribe之后做一些事情,你可以使用tap((运算符,或者只把逻辑放在subscribe((中,然后你可以抛出next/complete(subscribe(({next:x,complete:x(

最新更新