如何让Observable.flatMap等待解决

时间:2016-07-11 17:26:06

标签: javascript rxjs ava

使用RxJS和React,我遇到了如何在另一个Observable的map中生成的Observable.fromPromise中等待数据的问题。

我有异步助手:

const dataStreamGenerator = (url = CLIENTS_DATA_URL) => (
  Rx.Observable.fromPromise(fetch(url))
  .flatMap(response => Rx.Observable.fromPromise(response.json()))
  .catch(err => Rx.Observable.of(new Error(err)))
);

然后我actions.fetchClients$ Rx.Subject

actions.fetchClients$.map((url = CLIENTS_DATA_URL) => {
    const ts = Date.now();
    console.log('FETCH CLIENTS with: ', url);
    return dataStreamGenerator(url);
  }).map(val => {
    console.log('GOT DATA IN REDUCER: ', val);
    const error = (val instanceof Error) ? val.message : undefined;
    const data = error ? undefined : val;
    actions.receivedClientsData$.next({ data, error, ts: Date.now() });
    return (state) => state;
  })

(是的,试图在RxJS中模仿Redux)。

我测试了dataStreamGenerator,它运行正常(使用ava)并提供数据:

test('dataStreamGenerator', t => {
  const ds$ = dataStreamGenerator(CLIENTS_DATA_URL);
  return ds$.do((data) => {
    t.is(data.length, 10);
  });
});

(AVA自动订阅observable并使用它,因此无需订阅)。

但是actions.fetchClients$.map((url = CLI...第二张地图(开始...... console.log('GOT DATA IN REDUCER: ', val);...仍在获取Observable而不是dataStream $中的数据。

我在fetchClients $ code中尝试了mapflatMap的所有可能组合,但仍然没有运气。

我的测试代码是:

test.only('fetchClients$', t => {
  const initialState = {};
  actions.fetchClients$.next('http://jsonplaceholder.typicode.com/users');
  reducer$.subscribe(val => {
    console.log('TEST SUBSCRIBE VAL: ', val);
    t.pass();
  });
  actions.fetchClients$.next('http://jsonplaceholder.typicode.com/users');
});

我无法弄清楚如何等待Observable dataStreamGenerator(url);发出数据而不是Observable。

感谢。

1 个答案:

答案 0 :(得分:2)

您需要压缩从'x.c'::gvar返回的结果。

dataStreamGenerator

actions.fetchClients$ //This is now a flatMap .flatMap((url = CLIENTS_DATA_URL) => { const ts = Date.now(); console.log('FETCH CLIENTS with: ', url); return dataStreamGenerator(url); }); 运算符向下传递原样值,而map将展平flatMapObservables和{{1}这样他们的价值就会被传播。

它适用于测试用例,因为您直接订阅Arrays返回的Promises