简体   繁体   English

在 Redux Saga 中去抖动

[英]Debounce in Redux Saga

I found this useful little function to throttle based on which key is saving in Redux Saga我发现这个有用的小功能可以根据 Redux Saga 中保存的键进行节流

export default function* throttlePerKey(pattern:string, selector: Function, timeout:number, saga:any) {
    const set = new Set()
  
    while(true) {
      const action = yield take(pattern)
      const id = selector(action)
      const throttled = set.has(id)
     
      if (throttled) {
         
      } else {
        set.add(id)
        // Expire items after timeout
        yield fork(function* () {
          yield delay(timeout)
          set.delete(id)
        })
        yield call(saga, action)
      }
    }
  }

I'm trying now to make it debounce instead.我现在正在尝试让它去抖动。 So you always get the last one.所以你总是得到最后一个。

Any clues how to do that?任何线索如何做到这一点?

When the action happens for the first time, you can fork a task that sets a delay followed by a call to the saga, and save the task object.当动作第一次发生时,你可以 fork 一个设置延迟的任务,然后调用 saga,并保存任务对象。 If the action happens a second time soon after, you'll cancel the task and start another one.如果此操作不久后第二次发生,您将取消该任务并开始另一个任务。 Once enough time passes without any actions, the last task will make it past its delay, and call the saga.一旦足够的时间过去了而没有任何动作,最后一个任务就会超过它的延迟,并调用 saga。

export default function* debouncePerKey(pattern:string, selector: Function, timeout:number, saga:any) {
  const map = new Map()

  while(true) {
    const action = yield take(pattern)
    const id = selector(action)
    const existingTask = map.get(id)

    if (existingTask) {
      yield cancel(existingTask)
    }
   
    const newTask = yield fork(function* () {
      yield delay(timeout)
      map.delete(id)
      yield call(saga, action)
    })

    map.set(id, newTask)
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM