Answer a question

I found this useful little function to throttle based on which key is saving in 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?

Answers

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. 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.

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)
  }
}
Logo

React社区为您提供最前沿的新闻资讯和知识内容

更多推荐