RxJS 如何在用户输入完成后开始处理?
How to start processing after the user finishes typing with RxJS?
我有一个输入元素,我想在其中显示自动完成解决方案。我尝试用 RxJS 控制 HTTP 请求的数量。我想做的是:HTTP 请求仅在用户停止输入 1 秒后开始。
我有这个代码:
of(this.inputBox.nativeElement.value)
.pipe(
take(1),
map((e: any) => this.inputBox.nativeElement.value),
// wait 1 second to start
debounceTime(1000),
// if value is the same, ignore
distinctUntilChanged(),
// start connection
switchMap(term => this.autocompleteService.search({
term: this.inputBox.nativeElement.value
})),
).subscribe((result: AutocompleteResult[]) => {
console.log(result);
});
问题是 debounceTime(1000)
没有等到继续管道。 switchMap 在每个 keyup 事件后立即启动。
如何在用户完成输入后等待 1 秒?
问题是您的链条以 of(this.inputBox.nativeElement.value).pipe(take(1), ...)
开头,所以看起来您在每次按键时都在创建一个新的链条(带有新的去抖动计时器)。
相反,你应该只有一个链并将值推送到它的源:
const keyPress$ = new Subject();
...
keyPress$
.pipe(
debounceTime(1000),
...
)
...
keyPress$.next(this.inputBox.nativeElement.value);
为什么不使用 fromEvent
创建一个流?
我认为没有必要使用 distinctUntiChanged
,因为 input
事件仅在发生更改时触发(即用户 adds/removes 内容)。所以通过流的文本总是不同的。
const {fromEvent} = rxjs;
const {debounceTime, map} = rxjs.operators;
const text$ =
fromEvent(document.querySelector('input'), 'input')
.pipe(
debounceTime(1000),
map(ev => ev.target.value));
text$.subscribe(txt => {
console.log(txt);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.4/rxjs.umd.min.js"></script>
<input/>
我有一个输入元素,我想在其中显示自动完成解决方案。我尝试用 RxJS 控制 HTTP 请求的数量。我想做的是:HTTP 请求仅在用户停止输入 1 秒后开始。
我有这个代码:
of(this.inputBox.nativeElement.value)
.pipe(
take(1),
map((e: any) => this.inputBox.nativeElement.value),
// wait 1 second to start
debounceTime(1000),
// if value is the same, ignore
distinctUntilChanged(),
// start connection
switchMap(term => this.autocompleteService.search({
term: this.inputBox.nativeElement.value
})),
).subscribe((result: AutocompleteResult[]) => {
console.log(result);
});
问题是 debounceTime(1000)
没有等到继续管道。 switchMap 在每个 keyup 事件后立即启动。
如何在用户完成输入后等待 1 秒?
问题是您的链条以 of(this.inputBox.nativeElement.value).pipe(take(1), ...)
开头,所以看起来您在每次按键时都在创建一个新的链条(带有新的去抖动计时器)。
相反,你应该只有一个链并将值推送到它的源:
const keyPress$ = new Subject();
...
keyPress$
.pipe(
debounceTime(1000),
...
)
...
keyPress$.next(this.inputBox.nativeElement.value);
为什么不使用 fromEvent
创建一个流?
我认为没有必要使用 distinctUntiChanged
,因为 input
事件仅在发生更改时触发(即用户 adds/removes 内容)。所以通过流的文本总是不同的。
const {fromEvent} = rxjs;
const {debounceTime, map} = rxjs.operators;
const text$ =
fromEvent(document.querySelector('input'), 'input')
.pipe(
debounceTime(1000),
map(ev => ev.target.value));
text$.subscribe(txt => {
console.log(txt);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.4/rxjs.umd.min.js"></script>
<input/>