Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redux saga debounce and not just delay/cancel

Is there a way to debounce in Redux-Saga where subsequent calls are queued up behind the same delay, which keeps getting bumped by each new task added to queue. Similar to lodash's debounce https://lodash.com/docs#debounce.

I currently have something similar to redux-saga's debounce but removed the cancel part as I still want to action each task, I just want to bundle up all events to fire in a single thread later.

What I have currently:

const deferTime = 2000;
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));

export function* sendClickEvent (event, debounce) {
  if (debounce) {
    yield call(delay, deferTime);
  }
  yield put(action(event));
}

export function* clickSaga () {
  while (true) {
    const action = yield take(WIDGET_CLICKED);
    const state = yield select();
    const debounce = action.meta && action.meta.debounce;
    const payload = getWidgetClickPayload(state, action);
    const defaultData = getDefaultData(state);
    const event = {
      name: payload.name,
      data: Object.assign(defaultData, payload.data)
    };
    yield fork(sendClickEvent, event, debounce);
  }
}

I tried assigning fork to variable and then checking if that was running (.isRunning()) but didn't know how I could postpone that fork by another delay.

like image 454
Labithiotis Avatar asked May 23 '16 13:05

Labithiotis


1 Answers

Redux saga now has a debounce function/effect:

import { call, put, debounce } from `redux-saga/effects`

function* fetchAutocomplete(action) {
  const autocompleteProposals = yield call(Api.fetchAutocomplete, action.text)
  yield put({type: 'FETCHED_AUTOCOMPLETE_PROPOSALS', proposals: autocompleteProposals})
}

function* debounceAutocomplete() {
  yield debounce(1000, 'FETCH_AUTOCOMPLETE', fetchAutocomplete)
}
like image 133
Dominic Avatar answered Sep 17 '22 14:09

Dominic