【问题标题】:How to make Observable.flatMap to wait to resolve如何让 Observable.flatMap 等待解决
【发布时间】:2016-07-11 17:26:06
【问题描述】:

在使用 RxJS 和 React 时,我遇到了如何等待另一个 Observable 的地图中生成的 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$ 代码中尝试了 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。

谢谢。

【问题讨论】:

    标签: javascript rxjs ava


    【解决方案1】:

    您需要展平从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 运算符将值 按原样 传递到下游,而 flatMap 将扁平化 ObservablesArraysPromises,以便它们的值是被传播的。

    它在测试用例中有效,因为您直接订阅了dataStreamGenerator 返回的Observable

    【讨论】:

    • 谢谢@paulpdaniels。我之前甚至尝试过,但对测试输出感到困惑。似乎整个问题都在于 ava - 不等待 fetch 被解决并提前完成(在交付第一个值之后)。我应该在标签中添加ava
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 2020-10-17
    • 2019-07-06
    • 1970-01-01
    • 1970-01-01
    • 2014-11-12
    相关资源
    最近更新 更多