Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Run parallel saga effects without cancelling any of them

I'd like to run parallel effects with redux-saga, without throwing if an error happens.

Using the all effect from redux-saga, if:

One of the Effects was rejected before all the effects complete: throws the rejection error inside the Generator.

Basically, I want to wait for all effects to finish to trigger an action. I want to do something like this, but replacing all by something else:

export function* getSaga() {
  yield put(request());
  try {
    yield all([fetchItems1, fetchItems2, fetchItems3]);
    // Wait for all to resolve or get rejected, then dispatch succeed.
    yield put(actions.succeeded());
  } catch (e) {
    // This should never happen.
  }
}

I tried to use fork but it does cancel all other tasks if one failed. And I tried to use spawn but it doesn't wait for the tasks to finish to dispatch succeeded.

Using regular JS, there is a pattern called reflect which I'd like to apply with saga.

How can we achieve that?

Thanks

like image 221
alexmngn Avatar asked Jun 25 '18 11:06

alexmngn


1 Answers

Following the answer from the linked stackoverflow issue you can just as easily create a reflect saga and use it in the same way:

function* reflect(saga) {
  try {
    return { v: yield call(saga), status: 'fulfilled' }
  } catch (err) {
    return { e: err, status: 'rejected' }
  }
}
...
yield all([fetchItems1, fetchItems2, fetchItems3].map(reflect));

Working example: https://codesandbox.io/s/y2vx74jzqv

like image 190
Martin Kadlec Avatar answered Oct 20 '22 05:10

Martin Kadlec