我慢慢开始掌握rxjs,但有一段时间我会遇到困扰我的事情。
在这种情况下,它关于withLatestFrom运算符。下面的rxjs语句位于我的角度组件的OnInit方法中。当屏幕加载时,我看到getApiData()方法中的api调用执行了两次,同时我确定userEventSubject $从未被触发(这就是为什么我有第一个tap操作符)。
我期望发生的是getApiData()方法仅在调用userEventSubject $ .next()时调用,而且从不在屏幕加载时调用...
this.userEventSubject$
.pipe(
tap(creditNote => console.log('tapped!')),
takeUntil(this.ngUnsubscribe$),
filter(userEventData => this.checkValidity(userEventData)),
withLatestFrom(this.apiService.getApiData()),
mergeMap(([userEventData, apiData]) => {
let modalRef = this.modalService.show(ModalDialogComponent, {
initialState: { apiData }
});
let instance = <ModalDialogComponent>modalRef.content;
return instance.save.pipe(
mergeMap((info) =>
this.apiService.saveSomeData(userEventData, info).pipe(
catchError((error, caught) => {
instance.error = error;
return empty();
})
)
),
tap(response => modalRef.hide())
);
})
)
.subscribe((response) => {
this.handleResponse(response);
});
修正版:
this.userEventSubject$
.pipe(
tap(creditNote => console.log('tapped!')),
takeUntil(this.ngUnsubscribe$),
filter(userEventData => this.checkValidity(userEventData)),
mergeMap(userEventData =>
this.apiService.getApiData().pipe(
map(data => {
return { userEventData, data };
})
)
),
mergeMap(values => {
let modalRef = this.modalService.show(ModalDialogComponent, {
initialState: { data: values.apiData }
});
let instance = <ModalDialogComponent>modalRef.content;
return instance.save.pipe(
mergeMap((info) =>
this.apiService.saveSomeData(userEventData, info).pipe(
catchError((error, caught) => {
instance.error = error;
return empty();
})
)
),
tap(response => modalRef.hide())
);
})
)
.subscribe((response) => {
this.handleResponse(response);
});
答案 0 :(得分:2)
当您构建管道时,this.apiService.getApiData()
不在箭头功能中,但它会立即执行。将调用作为参数传递并不重要。表达式将像任何其他JS调用一样执行(尝试将console.log
放在同一个地方)。
您可以执行.concatMap(userData => this.apiService.getApiData().map(apidata => {userData, apiData}))
(或switchMap
),但这会始终调用API。我不知道什么是最适合你的需求。