Redux Observable的节流Ajax请求只满足一些条件

时间:2018-02-05 07:03:40

标签: javascript reactjs redux rxjs redux-observable

在我的reactjs redux应用程序中,我使用redux observable epics中间件来取消某些请求的ajax请求。

const epicRequest = $actions => {
  return $actions
         .ofType(MY_ACTION_TYPE)
         .debounceTime(500)
         .switchMap( action =>{
            // Doing Ajax
          })
} 

我的问题是当我按下某些按钮时我调用此动作,我有两种按钮都可以调用相同的动作,在这种情况下如果从第一个动作调用和第二个动作是不同的按钮我不想要去抖动,我只想在动作来自同一个按钮时去抖动。

2 个答案:

答案 0 :(得分:3)

要解决这个问题,你必须通过按钮调用传递额外的道具并从史诗中检查道具。

在组件按钮内单击呼叫,传递按钮标识。

onclick = () => {
  // assume arg name is 'from'
  this.props.yourAction('a') // can be 'a'/'b' ...
}

在您的动作调用中,传递您从按钮调用中获得的值。

const yourAction = (from) => {
  return { type: MY_ACTION_TYPE, from }
}

在减速器开关盒中

case MY_ACTION_TYPE:
  return {...state, from:action.from}

最后在您的史诗中间件函数中,使用.debounceTime(600)with this重复.debounce(),您可以将函数作为返回Observable.timer()的参数传递。所以你可以在这里检查你的道具并返回去抖时间。

let from = null
const epicRequest = $actions => {
    return $actions
        .ofType(MY_ACTION_TYPE)
        //.debounceTime(500)
        .debounce((action) => {
            // check button type is not yet set or not previous type
            const  timer = !from || (from !== action.from)  ? Observable.timer(0) : Observable.timer(600)
            // update button type
            from =  (from !== action.from) ? action.from : from
            // return Observable.timer()
            return timer
        })
        .switchMap( action =>{
            // Do your Ajax
        })
}

答案 1 :(得分:0)

目前尚不清楚你是否意味着你希望它们都是去抖动的,而是独立的,或者你只想要其中一个完全去抖动。我已经包含了两者的答案:

2个按钮独立去抖

高度建议让他们发出不同的动作类型,如果他们有不同的意图。如果意图是相同的,例如在列表项中重复相同的按钮,然后处理此问题的一种方法是使用groupBy通过按钮始终包含的某个唯一键独立地对每个按钮进行分组。

const epicRequest = action$ =>
  action$
    .ofType(MY_ACTION_TYPE)
    .groupBy(action => action.somethingUnique)
    .mergeMap(action$ =>
      action$
        .debounceTime(500)
        .switchMap(action => {
          // Doing Ajax
        })
    );

此示例假定每个按钮都包含唯一标识它的内容,包含为somethingUnique

groupBy

上的一些资源
  

警告:默认情况下groupBy永远不会完成()或清除它创建的每个组Observable,这意味着这可能是内存泄漏。无论您的应用程序是否重要,只有您可以知道。如果是,groupBy支持第三个参数持续时间选择器,您可以使用它来决定何时停止跟踪特定组 - 这并不意味着如果以后需要它会创建一个新的,只是当前的Observable代表它是完整的()'d。通常,如果没有某种明确的拆卸信号(例如远离页面的路线导航动作),在实践中干净地进行干净是很困难的。   有关详细信息,请参阅文档:http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-groupBy       durationSelector: function(grouped: GroupedObservable<K, R>): Observable<any>

1个按钮去抖,另一个按钮永远不会

这意味着他们有不同的意图。一个是打算被去抖,另一个不是,即使在他们的行动去贬值之后也是如此。

需要去抖动的动作可以发出完全不同的动作,如MY_ACTION_TYPE_DEBOUNCED,然后在去抖后发出正常的MY_ACTION_TYPE

const myActionTypeDebouncedEpic = action$ =>
  action$
    .ofType(MY_ACTION_TYPE_DEBOUNCED)
    .debounceTime(500)
    .map(action => ({
      ...action,
      type: MY_ACTION_TYPE
    }));

const myActionTypeEpic = action$ =>
  action$
    .ofType(MY_ACTION_TYPE)
    .switchMap(action => {
      // Doing Ajax
    });