Что касается вашего вопроса, я вижу, вам нужно какое-то время state
. Здесь ваш state
- это наблюдаемая pointerdown/move/dragging
, которая должна быть accumulated
или cleared
и, наконец, emitted
. Когда я вижу такой сценарий state
, мне всегда нравится использовать оператор scan :
Pre
Ради Простой пример, я не использовал ваши предопределенные наблюдаемые. Если у вас возникли проблемы с адаптацией указанного вами сценария использования указателя c к этому очень похожему, я могу попытаться обновить его, чтобы он был ближе к вашему вопросу
1. Что может представлять мое состояние
Здесь я использую enum [status] для последующего реагирования на событие, которое произошло раньше, и накопление [acc] для точек во времени
interface State {
acc: number[],
status: Status
}
enum Status {
init,
move,
finish,
escape
}
const DEFAULT_STATE: State = {
acc: [],
status: Status.init
}
2. Напишите функции, которые изменяют состояние
Ваше требование можно разделить на: накопить [указатель $ + позиция $], фини sh [указатель $], escape [escape $]
const accumulate = (index: number) => (state: State): State =>
({status: Status.move, acc: [...state.acc, index]});
const finish = () => (state: State): State =>
({status: Status.finish, acc: state.acc})
const escape = () => (state: State): State =>
({status: Status.escape, acc: []})
3. Сопоставьте свои функции с вашими наблюдаемыми
merge(
move$.pipe(map(accumulate)),
finish$.pipe(map(finish)),
escape$.pipe(map(escape))
)
4. Используйте функции сканирования, где ваше состояние с течением времени помещается
scan((acc: State, fn: (state: State) => State) => fn(acc), DEFAULT_STATE)
5. Обработка вашего мутированного состояния
Здесь мы хотим обрабатывать только если у нас есть конечное значение sh, поэтому мы фильтруем его
filter(state => state.status === Status.finish),
Пример внутреннего состояния
- move $ .next ('1') = Состояние: {status: move, a cc: ['1']}
- escape $ .next () = Состояние: {status: escape, cc: []}
- move $ .next ('2') = Состояние: {status: move, a cc: ['2']}
- finish $ .next () = Состояние: {status: fini sh, a cc: ['2']}
Выполняется stackblitz
К вашему сведению: довольно сложно прийти к такому решению проблем состояния с помощью rx js. Но как только вы поймете, что стоит за идеей, вы сможете использовать ее практически в каждом полном сценарии. Вы избежите побочных эффектов, придерживайтесь рабочего процесса rx js и сможете легко оптимизировать / отладить свой код.