javascript - 为顺序提取选择适当的运算符

标签 javascript functional-programming rxjs reactive-programming

我使用 RxJS 事件流和 fetch API 来发出两个连续的 HTTP 请求,其中第一个请求的结果必须传递到第二个请求。我已经很接近了,但是,合并两个流是有问题的:

const xhrUrlBase = "http://localhost:4556/api";
const xhrButton = document.querySelector("#xhr-rxjs");
const xhrTriggerClickStream = fromEvent(xhrButton, "click");
const xhr$ = of(xhrUrlBase).pipe(
  concatMap(url => {
    return fromFetch(`${xhrUrlBase}/a`).pipe(
      switchMap(response => response.json())
    );
  }),
  concatMap(fromFirstCall => {
    return fromFetch(`${xhrUrlBase}/b?fromA=${fromFirstCall.toB}`).pipe(
      switchMap(response => response.json()),
      map(fromSecondCall => ({
        fromFirstCall,
        fromSecondCall
      }))
    );
  })
);

/* option A */
const clickAndXhr$ = xhrTriggerClickStream
   .pipe(
     flatMap(() => xhr$)
   )

/* option B */
const clickAndXhr$ = combineLatest(
    xhrTriggerClickStream,
    xhr$
)

clickAndXhr$.subscribe(([, returnedDataFromBothHttpRequests]) => {
  console.log({ returnedDataFromBothHttpRequests }); // got data from both responses
});

选项 [A] 有效,但每次单击按钮时都会发出请求(我仍然不完全确定我在这里正确使用了 flatMap)。我想要 combineLatest 的功能,我可以像选项 [B] 一样从两者中获取最新的流。但是,该选项不会等待单击,并且 HTTP 请求是在页面加载时发出的。我需要的是介于两者之间的东西。

此练习中出现了几个问题:

1) 如何组合这些流,以便在单击按钮时发出一次 HTTP 请求,然后在后续的按钮单击时仅返回初始响应?

2) 设置代码(第 4 - 20 行)非常冗长且嵌套。有没有更惯用的方法来做到这一点。在我上面有 switchMap 的地方,flatMap 也可以工作(返回一个值),而 map 会给我(在最终订阅中)一个决心的 promise 。控制台显示 [[PromsieStatus]]: "resolved"[[PromiseValue]]:/* the right object */,但是我真的不明白怎么回事就像 rxjs switchMap 具有解开 promise 的能力一样。为什么这两个运算符都以这种方式工作?

3) 将 concatMap 更改为 flatMap 也不会改变功能。当出现如此多的重叠时,我如何知道哪个是合适的运算符?

最佳答案

您可以使用选项 a 并在 xhr$ 流末尾添加 shareReplay 运算符。

const xhr$ = of(xhrUrlBase).pipe(
  concatMap(url => {
    return fromFetch(`${xhrUrlBase}/a`).pipe(
      switchMap(response => response.json())
    );
  }),
  concatMap(fromFirstCall => {
    return fromFetch(`${xhrUrlBase}/b?fromA=${fromFirstCall.toB}`).pipe(
      switchMap(response => response.json()),
      map(fromSecondCall => ({
        fromFirstCall,
        fromSecondCall
      }))
    );
  })
  shareReplay(1),
);

关于javascript - 为顺序提取选择适当的运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59346293/

相关文章:

javascript - 将值从 javascript 传递到 PHP(使用隐藏字段)

javascript - 在 Ruby on Rails 中包含 Trianglify

javascript - "push-model"在 RxJS/Immutable.js/AngularJS 等上下文中的含义

javascript - 如何更改 RxJS 使用的默认调度程序?

angular - RxJS、Typescript 和可怕的 'Type Mismatch' 警告/错误

javascript - 如何在用户单击后退按钮或离开时执行功能。以及如何延迟它?

javascript - 在 Vuex/Nuxt 中绑定(bind)选择表单

f# - 从 F# 中的列表中提取单个元素

javascript - Ramda GroupBy - 如何按任何 Prop 分组

algorithm - Haskell groupBy 取决于累加器值