[EDIT 11/5] 在对一些建议的解决方案进行测试之后,我注意到我的某些rxjs导入是错误的(我是从'rxjs / internal'iso从'rxjs'导入的) 。因此,如果您遇到这样的错误,那就可以看看。
关于Stackoverflow的问题已经存在一些与取消订阅可观察项有关的问题,尽管这些问题都不会对我的特定问题有很大帮助。
在我的(“聊天”)应用程序中,我可以通过在搜索框中键入用户的名称来搜索用户。提取用户后,我想显示这些用户是否在线。
这是我的方法。
有一个BehaviorSubject用于捕获搜索词:
private term$ = new BehaviorSubject(null);
只要“可观察的术语”有新的价值,我就会开始寻找新用户:
users$: Observable<User[]> = this.term$.pipe(
filter(term => !!term),
switchMap(term => this.usersService.searchUsers(term))
);
但是我也想定期检查这些用户是否“在线”,因此我在Observable上方进行了这样的更改(请注意最后一行):
users$: Observable<any[]> = this.term$.pipe(
filter(term => !!term),
switchMap(term => this.usersService.searchUsers(term)),
switchMap(users => zip(...users.map(user => this.checkLoggedInF(user))))
);
对于所有用户,我创建一个可观察到的“间隔”。 checkedLoggedInF是一项功能,每隔5秒就会与服务器一起检查给定用户是否在线:
checkLoggedInF = user => {
return interval(5000).pipe(
switchMap(() => this.usersService.isLoggedIn(user.loginnaam).pipe(
map(loggedIn => ({...user, loggedIn}))
))
);
}
现在的问题是,每当有一个新的搜索词(在可观察的术语$上)时,都应取消订阅“ checkLoggedIn间隔”可观察的对象。我尝试在“ checkLoggedIn间隔”可观察到和父“ users $”可观察到的情况下都使用takeUntil运算符,但无济于事。同样,使用takeWhile运算符也无效。
答案 0 :(得分:1)
尝试在调用.tap()
的{{1}}之前使用switchMap
,并将checkLoggedInF
中的observable
保存在属性中
checkLoggedInF
或您也可以检查并在checkLoggedInF = user => {
this.checkLoggedInF$ = interval(5000).pipe(
switchMap(() => this.usersService.isLoggedIn(user.loginnaam).pipe(
map(loggedIn => ({...user, loggedIn}))
))
);
return this.checkLoggedInF$;
}
users$: Observable<any[]> = this.term$.pipe(
filter(term => !!term),
switchMap(term => this.usersService.searchUsers(term)),
tap(() => { this.checkLoggedInF$ && this.checkLoggedInF$.unsubscribe() })
switchMap(users => zip(...users.map(user => this.checkLoggedInF(user))))
);
中unsubscribe()
的另一个选项
checkLoggedInF
答案 1 :(得分:0)
最后,这是一个愚蠢的错误,我的某些“ rxjs导入”是错误的(我是从rxjs / internal导入)。修复导入后,switchMap会按预期运行(当“上游”更改时关闭订阅)。
简而言之:不要从'rxjs / internal'导入