Обработка многократного почтового запроса, используя угловой - PullRequest
0 голосов
/ 05 февраля 2019

У меня очень большая форма с элементами ввода html, и я делаю пост-запрос к webapi, когда происходит изменение входного значения.

Возможно, что через секунду сработает более 10 пост-запросов,Что приводит к несоответствию данных.Чтобы избежать этого сценария, я использовал мьютекс на стороне сервера для обработки одного запроса за раз.

string mutexName = $"{userId}-{id}";

using (MutexSlimWrapper mutex = MutexSlimDictionary.Instance.GetWrapper(mutexName))
{
    await mutex.WaitAsync();
}

Есть ли способ справиться с этим сценарием на стороне клиента, например debounce ?

Ответы [ 3 ]

0 голосов
/ 05 февраля 2019

В компоненте сделать что-то подобное:

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());
  }

Метод поиска принимает наблюдаемые строки, проходит через несколькооператоры, чтобы ограничить количество запросов, которые проходят, а затем вызывает метод searchEntries.debounceTime ждет, пока не появятся новые данные в течение указанного промежутка времени (в данном случае 400 мс), пока не пропустят следующие данные.distinctUntilChanged обеспечит прохождение только отдельных данных.Если пользователь что-то печатает, быстро стирает символ, а затем печатает обратно тот же символ, distinctUntilChanged отправит данные только один раз.

Наконец, введите свои данные:

<input (keyup)="searchTerm$.next($event.target.value)">
0 голосов
/ 05 февраля 2019

Я бы предложил вам комбинацию следующих трех операторов RxJS:

debounceTime например, debounceTime (400).Если вы не манипулируете полем в течение 400 мс, запрос будет отправлен

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 => ...)

Надеюсь, это поможет.

0 голосов
/ 05 февраля 2019

Вы можете передать valueChanges свойства ReactiveForm с rxjs debounceTime () , а также передать rxjs mergeMap () для вызоваваш API с измененным значением:

this.form
    .valueChanges
    .pipe(
        debounceTime(500),
        mergeMap((formData: any) => 
           this.yourService.yourServiceMethod(formData)
        )
    )
    .subscribe((data: any) => {
        // result from the webserver
    });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...