javascript - 如何防止从史诗开始两次相同的调用

标签 javascript redux rxjs redux-observable

REMOTE_DATA_STARTED 操作被调度时,我的史诗被唤醒,它使用 action.urlaction.owner 获取数据。

我需要确保不会对同一所有者/网址发起两个并发调用。完成对所有者/网址的调用后,稍后可以为同一所有者/网址启动另一个调用。

取消 不是我在这里寻找的,因为我不想取消现有请求,我想阻止启动新请求。

我觉得我需要 exhaustMapgroupBy 的混合,但我不知道从这里去哪里。

此时这是我的史诗,它拒绝所有并发调用,而不是所有者/url

const myEpic = action$ =>
  action$.ofType("REMOTE_DATA_STARTED").exhaustMap(action =>
    fakeAjaxCall().map(() => {
      return { type: "COMPLETED", owner: action.owner, url: action.url };
    })
  );

现场体验

我用一个失败的测试用例创建了这个测试项目。你能帮我完成这项工作吗?

https://codesandbox.io/s/l71zq6x8zl

正如您将看到的,test1_exhaustMapByActionType_easy 工作正常,test2_exhaustMapByActionTypeOwnerAndUrl 失败了。

确保展开控制台以查看测试结果。

最佳答案

肯定可以用 groupBy 和 exhastMap 以优雅的方式完成:

const groupedByExhaustMap = (keySelector, project) => 
  source$ => source$.pipe(
    groupBy(keySelector),
    mergeMap(groupedCalls => 
      groupedCalls.pipe(
        exhaustMap(project)
      )
    )
  );

const { delay, groupBy, mergeMap, exhaustMap } = Rx.operators;

const groupedByExhaustMap = (keySelector, project) => 
  source$ => source$.pipe(
    groupBy(keySelector),
    mergeMap(groupedCalls => 
      groupedCalls.pipe(
        exhaustMap(project)
      )
    )
  );

const calls = [ // every call takes 500ms
  {startTime: 0, owner: 1, url: 'url1'}, 
  {startTime: 200, owner: 2, url: 'url2'},
  {startTime: 400, owner: 1, url: 'url1'}, // dropped
  {startTime: 400, owner: 1, url: 'url2'},
  {startTime: 600, owner: 1, url: 'url1'}
];

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));

const simulateCallsOverTime$ = Rx.Observable.from(calls)  
  .pipe(
    mergeMap(call => Rx.Observable.of(call)
      .pipe(
        delay(call.startTime)
      )
    )
  );

simulateCallsOverTime$
  .pipe(
    groupedByExhaustMap(
      call => `${call.owner}_${call.url}`,
      async call => {
        await sleep(500); // http call goes here
        return call;
      }
    )
  )
  .subscribe(console.log);
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.8/Rx.js"></script>

关于javascript - 如何防止从史诗开始两次相同的调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49563059/

相关文章:

reactjs - React.js : How to get all props component expects?

reactjs - 在智能容器中定义函数时如何保持组件的纯粹性?

javascript - RxJS promise 链

javascript - 更改已打开的弹出窗口的 url

javascript - AngularJS 从 HTML 中的 <p> 获取值

javascript - MVC 不需要 ViewModel 上的双属性导致问题

reactjs - 全局 Redux 状态值

angular - 可观察,在 ngOnDestroy 中取消订阅不起作用

javascript - 为什么可观察性重新订阅热门

javascript - 如何通过附加到 Edge 浏览器在 VS Code 中进行调试?