взаимная рекурсия в rxjs - PullRequest
0 голосов
/ 24 октября 2018

Я знаю о expand для реализации рекурсии в rxjs.Я нашел много примеров того, как реализовать простую рекурсию, но ничего для взаимной рекурсии.

По сути, мне нужно поддерживать список результатов в актуальном состоянии.список фильтруется с помощью функции groom$ и обновляется / расширяется с помощью функции fetch$(), каждая из которых вызывается поочередно.

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

Вот пример кода:

const { of, timer, throwError } = Rx;
const { expand, switchMap, map, concat } = RxOperators;

function groom$(arr) {
    return timer(1000).pipe(map(() => arr.slice(1)));
}

function fetch$(arr) {
    return timer(250).pipe(map(() => [...arr, arr.slice(-1)[0] + 1]));
}

function multiRecurse(initialState, firstOp, transitions) {
  return firstOp(initialState).pipe(
      map((data) => ({data, op: transitions[firstOp]})),
      expand(({data, op}) => {
          if (transitions[op]) {
            return op(data).pipe(map((data) => ({data, op: transitions[op]})));
          } else return throwError(`Unknown next operation: ${op}`);
      }),
      map(({data}) => data)
  );
}

multiRecurse([0], fetch$, {
  [groom$]: fetch$,
  [fetch$]: groom$
});

Результирующая мраморная диаграмма (изhttps://rxviz.com/v/XJzlBj2o): marble diagram

...