Как очистить очередь.zip?

Я создал простую "систему игровых циклов", основанную на RxJS, где я запрашиваю действия у разных участников (включая пользователя) и объединяю их с оператором.zip.

Результатом является пошаговый игровой цикл, который приостанавливается только для анимации и для запроса действий пользователя.

Благодаря этой системе пользователь может ставить в очередь несколько действий, и система будет хранить их в.zip-операторе. Однако я хочу очистить эту "очередь", если пользователь решит передумать.

У меня есть скрипка: https://jsfiddle.net/az5pthng/6/

Представьте, что пользователь вводит последовательность a1, a2, a3, a4, затем думает секунду и решает изменить последовательность на b1, b2, b3, b4. Затем снова думает и набирает c1, c2, c3, c4.

В настоящее время у меня есть этот вывод, показывающий, что каждое нажатие клавиши записывается и воспроизводится:

(3) ["A", "B", "a1"]
(3) ["A", "B", "a2"]
1100
(3) ["A", "B", "a3"]
(3) ["A", "B", "a4"]
1723
(3) ["A", "B", "b1"]
(3) ["A", "B", "b2"]
(3) ["A", "B", "b3"]
(3) ["A", "B", "b4"]
(3) ["A", "B", "c1"]
(3) ["A", "B", "c2"]
(3) ["A", "B", "c3"]
(3) ["A", "B", "c4"]

Но я хочу этот вывод, указывающий, что всякий раз, когда queueTime$ выдает значение - queue$ получает "сброс" с новыми значениями:

(3) ["A", "B", "a1"]
(3) ["A", "B", "a2"]
1100
(3) ["A", "B", "b1"]
(3) ["A", "B", "b2"]
1700
(3) ["A", "B", "c1"]
(3) ["A", "B", "c2"]
(3) ["A", "B", "c3"]
(3) ["A", "B", "c4"]

РЕДАКТИРОВАТЬ: Вот картина, что я пытаюсь сделать: схема

Два потока - Turn и Q

Turn должен как-то запросить A и B и подождать, пока Q предоставит его значение, если оно есть. Когда Q предоставляет значение, Turn ждет некоторое время, а затем повторяется. Q, однако, разбивает его значения по времени (я думаю, с помощью.window?) И отбрасывает любое значение, которое не отправлено в Turn, если поступает новая последовательность.

2 ответа

Не уверен, правильно ли я понимаю ваш вопрос, но если вы хотите отложить очередь на запуск (поскольку пользователь может передумать, вы можете использовать debounceTime(1000), где 1000 в мс.
Если вы хотите очистить очередь, вы можете использовать тот же оператор с DifferentUntilChanged, чтобы распознать изменения и сделать то, что вы хотите! надеюсь, это поможет

Я это сделал! Хотя я чувствую, что это не так, как RxJS, но, по крайней мере, работает так, как я хочу. Если у вас есть лучшее решение - пожалуйста, напишите, я не очень рад иметь переменные и флаги "вне потока".

Мой способ - управлять очередью самостоятельно. А также есть флаг всякий раз, когда мне нужен ввод - если вся цепочка ожидает ввода, это правда, в противном случае нет. Основываясь на этом флаге, я либо помещаю нажатую клавишу в очередь, либо отправляю в цепочку напрямую.

input$.subscribe(({value, interval}) => {
    if (waitingForInput) {
    queue$.next(value);
    waitingForInput = false;
  } else {
    if (interval < DEBOUNCE_TIME) {
        queue.push(value);
    } else {
        queue.length = 0;
        queue.push(value);
    }
  }
});

А также:

// Request action from other entites
const requestAction = (x) => Rx.of(x);
// Request action from player
const requestQueueAction = () => {
    if (queue.length > 0) {
    return Rx.of(queue.shift());
  } else {
    waitingForInput = true;
    return queue$.pipe(op.take(1));
  }
}

Вот код: https://jsfiddle.net/az5pthng/7/

Другие вопросы по тегам