5

我目前从承诺转换为可观察的。我正在为我的反应应用程序使用 Redux-Observable。基本上,我正在寻找能够启用多个并发 ajax 调用并在所有可观察对象成功完成执行时返回响应的最佳运算符。这是我的应用程序的代码片段。

let epicPostAd = (action$, store, {ajax}) =>
  action$.ofType(POST_AD)
   .debounceTime(1000)
   .mergeMap(({ payload }) =>
     ajax(generateAjaxRequestSetting(POSTS_URL, 'post', payload,CT_JSON))
      .map(response => postAdSuccessful(response))
      .catch(e => Observable.of(postAdUnsuccessful(e.xhr.response)))
      .takeUntil(action$.ofType(LOCATION_CHANGE))
    )

这是一个简单的 ajax 请求,POST_AD_SUCCESSFUL当响应为 201 时发布给定的广告并调度,否则POST_AD_UNSUCCESSFUL在错误时调度。但问题是我想在有响应时制作后续的 ajax 可观察流。如

.map(response => /* start a stream of ajax observables then process the response */)

如果您向我展示实现这一目标的最佳方式,我将不胜感激。

4

2 回答 2

10

听起来您正在寻找forkJoin运营商

它将订阅您传递给它的所有 Observable,并且在它们全部完成后,它将从数组中的每个发出最后一个值。

在你的 Epic 中你想在哪里做这件事并不完全清楚,所以我只是做了一个通用的例子:

const somethingEpic = (action$, store, { ajax }) =>
  action$.ofType(SOMETHING)
    .mergeMap(() =>
      Observable.forkJoin(
        ajax('/first'),
        ajax('/second'),
        ajax('/third')
      )
      .do(results => {
        // the results is an array, containing each
        const [first, second, third] = results;
        console.log(first, second, third);
      })
      .map(results => ({
        type: 'SOME_RESULTS',
        results
      }))
    );

从技术上讲,它支持resultSelector您可以使用的最后一个参数,而不是map在它之后使用运算符,但我倾向于不使用它,因为我发现它不太清楚,在常见的 redux-observable 样式案例中只有微不足道的性能优势。但还是很高兴知道。可以方便地处理更多“数据规范化”的内容,而不是“将其转换为动作”的内容。

const somethingEpic = (action$, store, { ajax }) =>
  action$.ofType(SOMETHING)
    .mergeMap(() =>
      Observable.forkJoin(
        ajax('/first'),
        ajax('/second'),
        ajax('/third'),
        results => ({
          type: 'SOME_RESULTS',
          results
        })
      )
    );

另外,如果您问自己“我使用什么运算符?” 您应该尝试文档中的操作员向导:http ://reactivex.io/rxjs/

向下滚动到显示以下内容的部分:

您需要为您的问题寻找操作员吗?首先从下面的列表中选择一个选项:

  • 我有一个现有的 Observable,并且...
  • 我有一些 Observable 可以组合成一个 Observable,并且...
  • 我还没有 Observables,而且...

提示:打开你的 DevTools 来试验 RxJS。

尽管在这种情况下,forkJoin建议正确,但是当您单击它时,它尚未记录在案 :sadface: 但是谷歌搜索会显示许多不同的网站,解释它的作用以及如何使用它(在 RxJS 和其他 Rx 实现中其他语言)。喜欢这个有用的网站

于 2017-03-30T01:30:49.603 回答
0

这是我自己的问题的答案。尽管 JayPhelps 回答了,但我意识到我的问题不是很清楚。使用杰的推荐。我想出了以下内容:

let epicPostAd = (action$, store, {ajax, observable}) =>
  action$.ofType(POST_AD)
   .debounceTime(1000)
   .mergeMap(({ payload }) =>
     ajax(generateAjaxRequestSetting(POSTS_URL, 'post', payload, CT_JSON))
      .mergeMap(response =>
        observable.forkJoin(
          ajax(''),
          ajax('')
        )
      .do(res => {
        const [first, second, third] = results;
        console.log(first, second, third);
      })
      .map(res => postAdSuccessful(res))
    )
    .catch(e => observable.of(postAdUnsuccessful(e.xhr.response)))
    .takeUntil(action$.ofType(LOCATION_CHANGE))

)

所以这里是如何工作的。我发出一个发布请求,并在 ajax 请求完成执行后立即.mergeMap使用.forkJoin(). 然后处理结果

于 2017-03-30T02:11:17.230 回答