In general, fork is useful when a saga needs to run a non-blocking task. Non-blocking here means: the caller starts the task and continues execution, without waiting for completion.
There are many situations where this may be useful, but two main:
- grouping sagas in a logical area
- saving the link to the task in order to be able to cancel / join it.
The high-level saga may be an example of the first use case. You probably have something like:
yield fork(authSaga); yield fork(myDomainSpecificSaga);
Where authSaga is likely to include things like:
yield takeEvery(USER_REQUESTED_LOGIN, authenticateUser); yield takeEvery(USER_REQUESTED_LOGOUT, logoutUser);
You can see that this example is equivalent to what you suggested, calling the fork saga with a call to takeEvery . But in practice, you only need to do this for code organization purposes. takeEvery itself is a forked task, so in most cases this will be uselessly redundant.
An example of a second use case might be something like:
yield take(USER_WAS_AUTHENTICATED); const task = yield fork(monitorUserProfileUpdates); yield take(USER_SIGNED_OUT); yield cancel(task);
In this example, you can see that monitorUserProfileUpdates will be executed when the caller saga is renewed and will wait for the action USER_SIGNED_OUT to be sent. In addition, he can refer to it to cancel it if necessary.
For completeness, there is another way to start non-blocking calls: spawn . fork and spawn differ in how errors and undo bubbles from the child to the parent saga.
Vond
source share