首页 > 解决方案 > redux-observable testing forkJoin 大理石图

问题描述

我在使用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_DONELOAD动作。还是我完全误解了这一点?

标签: rxjsredux-observable

解决方案


如果您的测试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('|', {}),
};

因为我们有 40ms 的延迟,所以主图应该是这样的

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

推荐阅读