我有一种方法可以根据搜索词搜索员工的信息。
this._sub.pipe(
debounceTime(500),
filter(x => !!x),
distinctUntilChanged(),
switchMap(this.getResults.bind(this))
).subscribe((d: IDisplayEmp[]) => {
console.log('RES', d)
this.displayResults = d;
});
this._sub.next('mySearchTerm');
这很好用,如果发出新的API调用,则先前的API调用将被取消。但是问题来了。
仅在发出反跳后才取消活动的API调用。如果在反跳等待期间返回了活动的API调用,它仍会触发我的订阅。
我了解这是因为取消仅发生在switchmap的范围内。
是否可以对此进行重构,以便如果防抖动功能正在等待输入停止,它将取消所有未决的API调用?
可能是一种幼稚的方法,但是我尝试了如下所示的方法,它会发出值,但是现在没有反跳效果。
this._sub.pipe(
filter(x => !!x),
distinctUntilChanged(),
switchMap((x) => {
return of(x)
.pipe(
debounceTime(500),
this.getResults.bind(this)
);
})
).subscribe((d: IDisplayEmp[]) => {
console.log('RES', d)
this.displayResults = d;
});
感谢您的帮助。
答案 0 :(得分:2)
只要takeUntil
发出,就使用this._sub
取消您的请求。
this._sub.pipe(
debounceTime(500),
filter(x => !!x),
distinctUntilChanged(),
switchMap(searchTerm => this.getResults(searchTerm).pipe(
takeUntil(this._sub)
))
).subscribe((d: IDisplayEmp[]) => {
console.log('RES', d)
this.displayResults = d;
});
答案 1 :(得分:1)
我相信这应该对您有用:
使用concat
,以便第二次发射等待第一个发射完成。
const getFromAPI = (key: string): Observable<number> => {
return;
};
const keys: Observable<string> = new Observable();
concat(
keys.pipe(
debounceTime(500),
switchMap(key => getFromAPI(key)),
take(1)
)
).subscribe(console.log);
另一个例子:
const getFromAPI = (key: string): Observable<number> => {
return;
};
const keys: Observable<string> = new Observable();
const debouncedKeys = keys.pipe(debounceTime(500));
concat(
debouncedKeys.pipe(
switchMap(key => getFromAPI(key)),
take(1),
takeUntil(debouncedKeys)
)
).subscribe(console.log);
答案 2 :(得分:1)
不确定此处是否需要探索,但您可以将_sub转换为两个可观察值,一个将被反跳并返回原始查询,第二个未被反跳并返回null / undefined。
然后将它们合并并调用switchMap。
未消弹的可观察值应允许您取消呼叫,因为它也会到达切换映射。在这种情况下,switchMap可能返回空值或从不可见。并且只有当值附带的去观察的可观察对象时,才重新创建API调用。
类似的东西吗?
const debounced = this._sub.pipe(debounceTime(500), filter(x => !!x), distinctUntilChanged());
const undebounced = this._sub.pipe(map(_ => undefined));
merge(debounced, undebounced).pipe(
switchMap(val => {
if (val) {
return this.getResults(val);
} else {
return never;
}
})
);
答案 3 :(得分:0)
可接受的答案应该可以正常工作,但是我想与您分享另一种可以用timer
而不是debounceTime
来做到这一点的方法:
this._sub.pipe(
filter(x => !!x),
distinctUntilChanged(),
switchMap(val => timer(500).pipe(
switchMap(() => this.getResults(val))
))
).subscribe(...);
现在,如果排放量达到switchMap
,则timer
及其中的所有内容(包括有效的网络请求)都将被取消,并创建新的timer
。