0

In part of my application I need to save an item state to the server. However sometimes I will trigger a chain of submits each about 10ms away from the other.

State A
State B 
State C 
State D 

In this case I should really only submit State D.

My current solution is to have a takeLatest() on a saga with

function* submitItemStateSaga(action: Action<SubmitItemStatePayload>) {
    yield call(delay, THROTTLE_MS);
    //saga body
}

This seems kinda of hacky to me. Do you think this is okay, or is there a better way to do it using the inbuilt throttle() function.

Robert Lemiesz
  • 1,026
  • 2
  • 17
  • 29

2 Answers2

0

Is this 10ms determined by you or by your server's response? If the latter, sooner or later this approach will let you down.

That being said, you can do this

function* submitItemStateSaga(action) {
  const { submit, cancel } = yield race({
    submit: take('CONFIRM_SUBMISSION'),
    cancel: take('CANCEL_SUBMISSION'),
  })

  if (submit) {
    //saga body
  }
}


function* actionWatcher() {
  yield takeLatest('START_SUBMISSION', submitItemStateSaga)
}

And at the beginning of each submit on your chain you can dispatch the action to cancel the previous one and start the next. And then after you executed your entire chain you dispatch the action to confirm the submission.

0

It looks like like redux-saga's debounce() fits your use case better. It waits for incoming actions to slow down, then executes a task with the last action.

Both throttle() and debounce() are implemented via primitives like fork() and call(), and the implementations are provided in the docs. When the default behavior doesn't work for you, these implementations are a good start for writing your own custom solution.

Andrey Moiseev
  • 3,914
  • 7
  • 48
  • 64