我的表单非常大,带有html输入元素,当输入值发生变化时,我正在向webapi发出发布请求。
在很短的时间内,可能有超过10个发布请求被触发。这导致数据不一致。为了避免这种情况,我在服务器端使用了互斥锁来一次处理一个请求。
string mutexName = $"{userId}-{id}";
using (MutexSlimWrapper mutex = MutexSlimDictionary.Instance.GetWrapper(mutexName))
{
await mutex.WaitAsync();
}
有什么办法可以在客户端处理这种情况,例如反跳吗?
答案 0 :(得分:0)
您可以使用rxjs valueChanges用管道传输ReactiveForm的debounceTime()属性,也可以用管道传输rxjs mergeMap()来使用更改后的值调用api:
this.form
.valueChanges
.pipe(
debounceTime(500),
mergeMap((formData: any) =>
this.yourService.yourServiceMethod(formData)
)
)
.subscribe((data: any) => {
// result from the webserver
});
答案 1 :(得分:0)
在组件中执行以下操作:
searchTerm$ = new Subject<string>();
constructor(private searchService: SearchService) {
this.searchService.search(this.searchTerm$)
.subscribe(results => {
this.results = results.results;
});
}
在SearchService
中执行以下操作:
search(terms: Observable<string>) {
return terms.debounceTime(400)
.distinctUntilChanged()
.switchMap(term => this.searchEntries(term));
}
searchEntries(term) {
return this.http
.get(this.apiUrl + term)
.map(res => res.json());
}
Search方法采用可观察到的字符串,通过一些运算符来限制通过的请求数量,然后调用searchEntries
方法。 debounceTime
等到在指定的时间内(在这种情况下为400ms)没有新数据,直到下一个数据通过为止。 distinctUntilChanged
将确保仅传递不同的数据。如果用户键入了某些内容,则快速擦除了一个字符,然后又键入了相同的字符,distinctUntilChanged
只会发送一次数据。
最后在输入中执行以下操作:
<input (keyup)="searchTerm$.next($event.target.value)">
答案 2 :(得分:0)
我建议您结合使用以下三个RxJS运算符:
debounceTime
,例如debounceTime(400)。如果您在400ms内未操作该字段,则会提交请求
distinctUntilChanged
在400毫秒后(请参见debounceTime),将检查自上次发出值以来内容是否已更改。如果是这样,将调用下一个管道。如果该值未更改,则不会发送任何请求。
switchMap
可以使用-当进行新的搜索时,不再需要挂起的结果->这意味着仅处理最新的结果,因此,如果服务器在回答最后一个结果时很慢,则会处理触发订阅。
所以代码看起来像
请注意,这是通过RxJS 6.0或更高版本完成的,没有rxjs-compat。
如果使用旧版本,则不需要管道。
yourFormControl.valueChanges.pipe(
debounceTime(400),
distinctUntilChanged(),
switchMap(res => ...))
.subscribe((val) => ...)
RxJS 5.0解决方案
yourformControl.valueChanges
.debounceTime(400)
.distinctUntilChanged()
.switchMap(res => ...)
.subscribe(val => ...)
希望这会有所帮助。