Я как-то изо всех сил пытаюсь придумать мраморную диаграмму при использовании forkJoin. Мой вывод почему-то всегда говорит, что подписка пуста.

Псевдокод:

// epic
const epic = (action$) => action$.pipe(
  ofType('SAVE'),
  mergeMap(() => {
    const requests = [
      getJSON('/a'),
      getJSON('/b'),
      getJSON('/c'),
    ];
    return forkJoin(
      ...requests
    ).pipe(
      mergeMap(() => [
        { type: 'SAVE_DONE'},
        { type: 'LOAD'},
      ])
    );
  })
);

// mock
const dependencies = {
  getJSON: url => cold('g', {
    g: { url }
  })
};

// input
hot('i', {
  i: { type: 'SAVE' }
} 
// output??

ForkJoin идет параллельно, но на мраморной диаграмме последовательно? ggg ? Причина afaik, если мы посмотрим на весь поток, это igggxy, где x и y - действия SAVE_DONE и LOAD. Или я совершенно неправильно это понимаю?

1
gerasalus 17 Апр 2020 в 15:55
2
Это все странно. forkJoin испускается только тогда, когда все его исходные Observable испускаются хотя бы один раз и завершаются. Вы используете cold('g'), что означает, что этот Observable никогда не завершится. Вам придется изменить его на cold('(g|)'), если бы вы могли сделать демонстрацию stackblitz, которая помогла бы.
 – 
martin
17 Апр 2020 в 20:30
Идеальный! спасибо :) это вместе с ожидаемым (ab) отлично работает. Можете ли вы объяснить немного больше о том, как полный оператор помогает здесь?
 – 
gerasalus
17 Апр 2020 в 20:52
Думаю, объяснять особо нечего. forkJoin требует завершения всех исходных Observable, поэтому | важен.
 – 
martin
18 Апр 2020 в 10:53
Когда у вас есть (a|), это означает, что источник отправит значение и завершит в пределах одного и того же кадра; по существу это означает: subscriber.next('a'); subscriber.complete().
 – 
Andrei Gătej
19 Апр 2020 в 01:06

1 ответ

Если тест epic вы должны ожидать 2 выброса SAVE_DONE и LOAD один за другим, для этого вам нужны круглые скобки.

Тогда схема должна выглядеть так:

cold('(ab)', {
    a: { type: 'SAVE_DONE'},
    b: { type: 'LOAD'},
  })
};

Поскольку зависимость getJSON зависит от вас, там вы можете фактически имитировать ошибки или задержки в загрузке, победителем является самый длинный.

const dependencies = {
  getJSON: url =>
    url === '/a'
      ? cold('--a|', {
        a: { url }
      }) :
    url === '/b'
      ? cold('---a|', {
        a: { url }
      }) :
    url === '/c'
      ? cold('----a|', {
        a: { url }
      }) :
    cold('|', {}),
};

И поскольку у нас есть задержка 40 мс, основная диаграмма должна быть такой

cold('----(ab)', {
    a: { type: 'SAVE_DONE'},
    b: { type: 'LOAD'},
  })
};
0
satanTime 21 Май 2020 в 01:31