Реализация отложенной очереди с помощью RxJS Observable

#javascript #angular #rxjs

#javascript #угловой #rxjs

Вопрос:

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

Учитывая, что пользователь может нажать кнопку, которая увеличивает счетчик. При запуске счетчик равен 0, и пользователь нажимает два раза за 500 мс. Первый щелчок увеличивает счетчик на единицу, но второй щелчок приведет к задержке действия на 500 мс. Затем пользователь ожидает более 500 мс и нажимает. Третий щелчок должен сразу увеличить счетчик, поскольку, так сказать, не выполняется никакого другого действия по увеличению. Если третий щелчок происходит в окне 500 мс, ему приходится ждать, пока другой завершится.

Да, я думаю, я понял вашу проблему @estus. Каким-то образом было бы необходимо зарегистрировать, где выполняется последнее действие. Сохранение времени, когда оно было отправлено или что-то в этом роде.

Учитывая, что первый щелчок произошел за 300 мс до этого, и происходит новый щелчок. В этом случае 2-й щелчок должен ждать всего 200 мс. введите описание изображения здесь

Here
Update1: основан ли код на ответе Доруса

Комментарии:

1. Это два разных случая. Публикация существующего кода поможет получить ответ, соответствующий вашему случаю (если таковой имеется).

2. Кода пока нет. Я собираюсь реализовать что-то в jsbin, используя ответ Доруса. Наблюдаемый похож на хранителя. Он не позволяет другим проходить, пока пассажир не покинет буферную зону, иначе. достаточно далеко от ворот. Если в буферной зоне никого нет, следующий пассажир может пройти сразу. Это то, что мне нужно реализовать наблюдаемым образом.

3. В первом случае, пожалуйста, укажите, какой ввод вы ожидаете, а какой вывод (с помощью ms timeline), поскольку описание недостаточно конкретное. Опять же, второй случай — это не просто пример, а другой случай, и неясно, что должно произойти с 3-м щелчком мыши в окне 500 мс. Если ваш вопрос требует рецептов для обоих случаев, пожалуйста, укажите это явно.

4. Пассажиры аналогичны щелчкам пользователя, поэтому очередь не обязательна, я просто подумал, что так проще объяснить / реализовать.

5. То, что вы описываете, довольно близко к общему дросселированию / деблокированию. Я не могу быть уверен, но, возможно, throttleTime operator делает именно то, что вы хотите.

Ответ №1:

Вы можете использовать concatMap :

 delay = 1000; // delay in ms
queue.concatMap(e =>
    Rx.Observable.of(e) // emit first item right away
      .concat(Rx.Observable.empty().delay(delay)) // delay next item
  )
 

Комментарии:

1. Удивительно! Блестяще!

2. К ВАШЕМУ СВЕДЕНИЮ. Мне пришлось немного изменить код, чтобы избежать ошибки: Rx.Observable.empty().delay(delay)

3. @apreg Ой, правильно, я исправил свой ответ для других 🙂