Rxjs - таблица с кнопками, подождите некоторое время после последнего нажатия кнопки перед запросом - PullRequest
0 голосов
/ 07 июня 2019

Мне бы хотелось, чтобы ваша помощь была использована для таких вещей, как удаление уведомлений.

По сути, у моих пользователей есть список уведомлений, которые они могут пометить как прочитанные.
Теперь,мой бэкэнд очень вялый (и я не могу его контролировать).
Прямо сейчас, когда пользователь нажимает на кнопку уведомления:

  1. Запросна бэк-энде делается отметка уведомления, затем после бэк-энда обновите данные другим запросом;
  2. запись изменена в памяти приложения, вид изменен
  3. Обновленные данные из 1. возвращается, вид изменен

Это приводит к чему-то вроде этого (используя Angular's * 1023)*):

markAsRead(id: string): void {
  this.http.post(url, body, options)
  .subscribe(() => this.reloadNotifications());

  this.markAsReadInternal(id);
}

А вот и проблема: когда мой пользователь решает сделать одно действие, все хорошо.Но когда пользователь решает прочитать много уведомлений, представление может изменяться много раз при обновлении данных.

Я вижу способ предотвратить проблему, но это будет означать

  1. Кнопка нажата;
  2. Сохранение идентификатора в массиве;
  3. Ожидание X миллисекунд для следующего щелчка;
  4. Если щелчок произошел обратно к 2. , иначе
  5. Отправьте запрос с массивом идентификаторов и обновите данные

Любая помощь, чтобы перевести это в код rxjs?

Бонусpoint : мои данные обновляются каждые 5 секунд в любом случае ...

Ответы [ 2 ]

1 голос
/ 07 июня 2019

Нажатия кнопок вызывают функцию:

<button (click)="buttonClicked()"></button>

Сохранение нажатий кнопок как темы / наблюдаемой:

private buttonClick$: Subject<any> = new Subject();

Издает новое значение для каждого щелчка:

buttonClicked() {
  this.buttonClick$.next();
  // this.buttonClick$.emit(); // One of these is deprecated, can't remember which
}

Удушение нажатий кнопок "Получить":

getButtonClicks() {
  return this.buttonClick$.pipe(
    throttleTime(5000)
  )
}

И затем вы можете сделать что-то вроде:

getButtonClicks().subscribe(() => {
  // Do something with throttled button clicks
});

Чтобы сделать заметное из кликов, вы также можете использовать это вместо вашей темы:https://www.learnrxjs.io/operators/creation/fromevent.html

Редактировать:

Таким образом, вы хотите сохранить щелчки между регулировками.Вы можете сделать это следующим образом:

getButtonClicks() {
  return this.buttonClick$.pipe(
    buffer(this.buttonClick$.pipe(
      debounceTime(5000)
    ))
  )
}

И затем вы все равно вызываете свой BE API:

getButtonClicks().subscribe((clicks) => {
  // Do something with debounced clicks
  // console.log(clicks);
});
0 голосов
/ 17 июня 2019

Вы можете лучше использовать buffer & debounceTime, затем throttleTime.

throttleTime против debounceTime

throttleTime сначала (я думаю, это не то, что выхотите), а затем подождите N мс.

https://rxjs -dev.firebaseapp.com / api / operator / buffer - buffer

debounceTime ждетдля N мс после последнего события и генерируется, если дальнейшие события не отправляются.

https://rxjs -dev.firebaseapp.com / api / operator / debounceTime - debounceTime

buffer(observable) означает collect items until parameter observable emits, а debounceTime(N) означает N ms after last emit.

Вы можете понимать это как «собирать предметы до» (buffer) «1000 мс после последнего щелчка» (debounceTime) ".

Это рабочая симуляция.

// Mock notification button click event
const click$ = Rx.fromEvent(document.getElementById('notification'), 'click');

// Mock http request
function markAsRead(...ids: string[]) {
  return Rx.timer(Math.random() * 2000)
    .pipe(
      RxOp.mapTo('marked!'),
    );
}

click$
  .pipe(
    RxOp.mapTo((Math.random() * 1000).toFixed()), // Mock ID, random
    RxOp.bufferWhen(() => click$.pipe(RxOp.debounceTime(1000))), // your 'certain time'
    RxOp.switchMap(ids => markAsRead(...ids)), // call http request
  )
  .subscribe(value => log(value));

https://stackblitz.com/edit/kuroneko0441-rxjs-test-1ynvps?file=index.ts&devtoolsheight=50

...