Non-blocking calls with fork and join

Show how to perform non-blocking calls in Redux-Saga using the fork and join effects, allowing multiple tasks to be initiated concurrently.
import { fork, join } from 'redux-saga/effects';

function* watchAndLog() {
  // Some logging functionality

function* fetchData() {
  // Function to fetch data

function* mainSaga() {
  // fork returns a Task object for each saga
  const logFork = yield fork(watchAndLog);
  const fetchTask = yield fork(fetchData);

  // Non-blocking calls, both sagas are initiated concurrently

  // join pauses until the specified task completes
  yield join(fetchTask);

  // Optional: join the logging task or let it run independently
  // yield join(logFork);
This example demonstrates how to perform non-blocking calls using fork and join effects in Redux-Saga. The fork effect is used to initiate two tasks, 'watchAndLog' and 'fetchData', concurrently without blocking the code execution. The join effect is then used to wait for the 'fetchData' task to complete, ensuring that any necessary data is fetched before proceeding. The 'watchAndLog' task can either be waited upon using join or run independently.