按照switchMap的定义
在每次发射时,先前的内部可观测值(您提供的功能的结果)都会被取消,并订阅新的可观测值。您可以通过切换到新的可观察到的短语来记住这一点。
现在,我有这样的代码
const source = timer(0, 5000).pipe(map(x=>`${x}`));
const example = source.pipe(switchMap((f) => interval(1000).pipe(map(y=>`f${f}-s${y}`))),take(20));
const subscribe = example.subscribe(val => console.log(val+' '+ new Date().getSeconds()));
Run Code Online (Sandbox Code Playgroud)
结果是这样
我的问题是
25秒-调用外部函数且尚未触发内部函数,因此外部函数的最新值为0,并且内部函数的默认值为0,因为它尚无值f0-s0 25
第26秒-内部函数被调用,理想情况下该值应为0,因为该函数是第一次被调用,但值为1,即。f0-s1 26
30秒-调用外部函数,它将内部函数值重置为0,即。f1-s0 30
为什么内部功能在第35秒被复位,仍然还有1秒
我觉得很难理解这个概念,谢谢
比方说,我有一系列行动。每个动作都被分配了一些id。像这样:
const actions$ = of({ id: 1 }, { id: 2 }, { id: 1 });
Run Code Online (Sandbox Code Playgroud)
现在,对于每个操作,我想在 switchMap 中执行一些逻辑:
actions$.pipe(switchMap(a => /* some cancellable logic */)).subscribe(...);
Run Code Online (Sandbox Code Playgroud)
问题在于每个发出的操作都会取消之前的“某些可取消的逻辑”。
是否可以根据操作id (最好是运算符)取消“某些可取消逻辑” ?就像是:
actions$.pipe(switchMapBy('id', a => /*some cancellable logic */)).subscribe(...)
Run Code Online (Sandbox Code Playgroud)
本质上,switchMap的当前行为:
1. actions$发出 id #1。switchMap订阅嵌套的 observable。
2. actions$发出 id #2。switchMap取消订阅先前的嵌套可观察值。订阅新的。
3. actions$发出 id #1。switchMap再次取消订阅先前的嵌套可观察值。订阅新的。
预期行为:
1. actions$发出 id #1。switchMap订阅嵌套的 observable。
2. actions$发出 id #2。switchMap再次订阅嵌套的 …
我正在使用 Angular (9) 驱动的 Bootstrap (6.1.0) TypeAhead 并定义其搜索函数,如下所示:
search = (text$: Observable<string>) => {
return text$.pipe(
debounceTime(200),
distinctUntilChanged(),
// switchMap allows returning an observable rather than maps array
switchMap((searchText) => {
if (!searchText || searchText.trim().length == 0) {
// when the user erases the searchText
this.dealerRepUserID = 0;
this.dealerRepChanging.emit(this.dealerRepUserID);
return EMPTY;
}
else if (this.dealerID == this.hostOrganizationID) {
// get a list of host reps
return this.myService.getHostRepsAutoComplete(searchText, this.includeInactive);
} else {
// get a list of dealer reps
return this.myService.getDealerReps(this.dealerID, …Run Code Online (Sandbox Code Playgroud) 更推荐哪种方法来组合多个 LiveData:使用MediatorLiveData或switchMap?
// MediatorLiveData approach
fun <A, B, C> combine(
liveData1: LiveData<A>,
liveData2: LiveData<B>,
onChanged: (A?, B?) -> C
): MediatorLiveData<C> {
return MediatorLiveData<C>().apply {
addSource(liveData1) {
value = onChanged(liveData1.value, liveData2.value)
}
addSource(liveData2) {
value = onChanged(liveData1.value, liveData2.value)
}
}
}
// switchMap approach
fun <A, B, C> combine(
liveData1: LiveData<A>,
liveData2: LiveData<B>,
onChanged: (A, B) -> C
): LiveData<C> {
return liveData1.switchMap { a ->
liveData2.map { b ->
onChanged(a, b)
}
}
}
Run Code Online (Sandbox Code Playgroud)
该 …
假设我有这样的代码:
this.apiService.getUrlForPhoto('photo1')
.switchMap((url) => {
return this.apiService.uploadPhotoToProvidedUrl(url);
})
.switchMap((response) => {
return this.apiService.confirmPhotoUpload(confirmationToken);
})
.subscribe((response) => {
if (response.confirmed) {
console.log('Success');
}
});
Run Code Online (Sandbox Code Playgroud)
首先是http get,它返回我可以发布新照片的url,其次是http放在我必须上传照片的地方,第三个是http post,我必须确认照片已上传到该url。
我的问题是可以将 url 传递给第二个 switchMap 吗?在第二个 switchMap 中,我收到了来自 uploadPhotoToProviderdUrl 方法的响应,但如何从以前的方法获得响应?
我在我的 angular 8 项目中有一个 observable,并且订阅了 ngOnInit()。
export class ChartComponent implements OnInit {
urlSubject: Subject<string> = new Subject();
isLoading: BehaviorSubject<boolean> = new BehaviorSubject(false);
chartData: BehaviorSubject<any[]> = new BehaviorSubject<any[]>([]);
dataSubscription: Subscription;
dataObservable: Observable<any> = this.urlSubject.pipe(
switchMap((url: any) => this.httpClient.get<any[]>(url))
)
ngOnInit() {
this.dataSubscription = this.dataObservable
.pipe(tap(() => this.isLoading.next(true)))
.pipe(map((response: any) => response.result))
.subscribe((response: any) => this.chartData.next(response),
() => this.isLoading.next(false),
() => this.isLoading.next(false));
this.urlSubject.next(this.data.settings.dataEndpoint)
}
}
Run Code Online (Sandbox Code Playgroud)
但是复杂的方法不会触发订阅。
我正在订阅chartData那种类型是BehaviourSubject. 所以我不订阅urlSubject。因为 url 可能会随时更改 searh 或 filter 参数。
我正在使用 finilize …
我试图使用subscription.unsubsribe取消待处理的http请求,如下所示:
getAgentList(pageNumber: number, filter: string): any {
let requestUrl: string = 'api/service/agents_search?ACCT='
+this.accountId;
if ( this.subscription ) {
this.subscription.unsubscribe();
}
this.subscription = this.backEndCommService.getData(requestUrl)
.subscribe(
(res: any) => {
let serverResponse: ServerResponse = new
ServerResponse(this.accountId, pageNumber, res.search_results,
res.resultRows, res.pageSize, res.resultPages)
this._agentListData.next(serverResponse);
},
(err: HttpErrorResponse) => {
let errorMessage: string;
if (err instanceof TypeError) {
errorMessage = 'Script error: ' + err.message;
}
console.log(errorMessage);
});
}
Run Code Online (Sandbox Code Playgroud)
我想知道如何将switchMap应用于此代码,以便杀死对URL的挂起请求(例如,当第一次搜索花费大量时间,而第二次输入时要输入第一个,而我想取消第一个,则自动完成搜索输入)。
我在角度应用程序中使用以下代码。我使用的 RxJSmap调用类似于数组的map使用方式。在阅读了 RxJSswitchmap运算符后,我不确定是否应该使用mapor switchmap。我是否应该使用switchmap这样从调用返回的可观察对象http被关闭,这样就不存在内存泄漏?
getPeopleForTypeahead(term: string): Observable<IPersonForTypeahead[]> {
var peopleUrl = `https://localhost:5001/api/peoplesearch?name=${term}`;
return this.http.get<any>(peopleUrl)
.pipe(
map(pl => {
return this.peopleAsFlattened(pl.peopleList).reduce((p, c) => p.concat(c));
}),
catchError(this.handleError('getPeopleForTypeahead', []))
);
}
peopleAsFlattened = (pla: IPeopleList[]) => {
return pla.map(pl => pl.people.map(p => {
return {
id: p.id,
fullName: p.fullNames[0].firstName + " " + p.fullNames[0].lastName
};
}));
}
Run Code Online (Sandbox Code Playgroud) 我有一个简单的目标,即创建一个可观察的对象,以发出世界上所有国家/地区的列表。observable 的类型是Country[],即存储值的类型为对象数组。然而,当传递给 时switchMap,它会神奇地转换为 type Country。我不知道是什么原因导致这种行为,如果它不是偶然的,在我这边。这是有问题的函数:
public getAllCountries(): Observable<Country[]> {
const getAppState = createFeatureSelector<ServicesState>('services');
const getCountries = createSelector( getAppState, (state: ServicesState): Country[] => state.countries);
// as you can see, this is the NGRX store slice that must be of type Observable<Country[]>
const countriesFromStore$ = this.store.pipe(select(getCountries));
return countriesFromStore$.pipe(
// this is the switchMap that causes the error
switchMap( countries => {
// this is the return statement that somehow converts an array of objects into a single …Run Code Online (Sandbox Code Playgroud) switchmap ×9
rxjs ×8
angular ×3
javascript ×2
observable ×2
android ×1
angular8 ×1
angular9 ×1
arrays ×1
httprequest ×1
kotlin ×1
ngrx ×1
rxjs6 ×1
typescript ×1