CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-redux-saga

Saga middleware for Redux to handle side effects using ES6 generators

Pending
Overview
Eval results
Files

concurrency-effects.mddocs/

Concurrency Effects

Effects for managing concurrent execution, forking tasks, and coordinating multiple asynchronous operations.

Capabilities

fork

Creates an effect that performs a non-blocking call on a function. Returns a Task object representing the forked execution.

/**
 * Perform non-blocking call, returns Task object
 * @param fn - Function to fork (generator, async, or sync)
 * @param args - Arguments to pass to the function
 * @returns ForkEffect that resolves with Task
 */
function fork<Fn extends (...args: any[]) => any>(
  fn: Fn,
  ...args: Parameters<Fn>
): ForkEffect<SagaReturnType<Fn>>;

/**
 * Fork method on context object
 * @param ctxAndFnName - Array of [context, methodName]
 * @param args - Arguments to pass
 * @returns ForkEffect
 */
function fork<Ctx extends { [P in Name]: (this: Ctx, ...args: any[]) => any }, Name extends string>(
  ctxAndFnName: [Ctx, Name],
  ...args: Parameters<Ctx[Name]>
): ForkEffect<SagaReturnType<Ctx[Name]>>;

Usage Examples:

import { fork, take, cancel } from "redux-saga/effects";

function* backgroundTask() {
  while (true) {
    console.log("Background work...");
    yield delay(1000);
  }
}

function* mainSaga() {
  // Fork a background task
  const task = yield fork(backgroundTask);
  
  // Fork multiple tasks
  const task1 = yield fork(fetchUser, 1);
  const task2 = yield fork(fetchUser, 2);
  
  // Parent waits for all forked tasks to complete
  // before terminating (unless cancelled)
}

spawn

Same as fork() but creates a detached task. A detached task remains independent from its parent and acts like a top-level task.

/**
 * Create detached task independent from parent
 * @param fn - Function to spawn
 * @param args - Arguments to pass
 * @returns ForkEffect with detached task
 */
function spawn<Fn extends (...args: any[]) => any>(
  fn: Fn,
  ...args: Parameters<Fn>
): ForkEffect<SagaReturnType<Fn>>;

Usage Examples:

import { spawn } from "redux-saga/effects";

function* parentSaga() {
  // Spawn detached task
  yield spawn(independentTask);
  
  // Parent can complete without waiting for spawned task
  // Spawned task continues running independently
}

join

Creates an effect that waits for the result of a previously forked task. If the joined task is cancelled, the cancellation propagates to the saga executing the join effect.

/**
 * Wait for result of previously forked task
 * @param task - Task object from fork effect
 * @returns JoinEffect that resolves with task result
 */
function join(task: Task): JoinEffect;

/**
 * Wait for results of multiple tasks
 * @param tasks - Array of Task objects
 * @returns JoinEffect that resolves when all tasks complete
 */
function join(tasks: Task[]): JoinEffect;

Usage Examples:

import { fork, join } from "redux-saga/effects";

function* coordinatorSaga() {
  // Fork multiple tasks
  const task1 = yield fork(fetchUser, 1);
  const task2 = yield fork(fetchUser, 2);
  
  // Wait for both to complete
  const [user1, user2] = yield join([task1, task2]);
  
  // Or join one at a time
  const result1 = yield join(task1);
  const result2 = yield join(task2);
}

cancel

Creates an effect that cancels a previously forked task. Cancellation propagates to all child tasks and current effects.

/**
 * Cancel a previously forked task
 * @param task - Task object to cancel
 * @returns CancelEffect
 */
function cancel(task: Task): CancelEffect;

/**
 * Cancel multiple tasks
 * @param tasks - Array of tasks to cancel
 * @returns CancelEffect
 */
function cancel(tasks: Task[]): CancelEffect;

/**
 * Self-cancellation (cancel current task)
 * @returns CancelEffect for self-cancellation
 */
function cancel(): CancelEffect;

Usage Examples:

import { fork, cancel, take, cancelled } from "redux-saga/effects";

function* cancellableTask() {
  try {
    while (true) {
      yield call(doWork);
      yield delay(1000);
    }
  } finally {
    if (yield cancelled()) {
      console.log('Task was cancelled');
      // Cleanup logic
    }
  }
}

function* controllerSaga() {
  const task = yield fork(cancellableTask);
  
  // Cancel on user action
  yield take('CANCEL_BACKGROUND_TASK');
  yield cancel(task);
}

cancelled

Creates an effect that returns whether the current generator has been cancelled. Typically used in finally blocks for cleanup.

/**
 * Check if current generator has been cancelled
 * @returns CancelledEffect that resolves with boolean
 */
function cancelled(): CancelledEffect;

all

Creates an effect that runs multiple effects in parallel and waits for all of them to complete. Similar to Promise.all().

/**
 * Run multiple effects in parallel, wait for all to complete
 * @param effects - Array of effects to run in parallel
 * @returns AllEffect that resolves with array of results
 */
function all<T>(effects: T[]): AllEffect<T>;

/**
 * Run labeled effects in parallel
 * @param effects - Object with labeled effects
 * @returns AllEffect that resolves with object of results
 */
function all<T>(effects: { [key: string]: T }): AllEffect<T>;

Usage Examples:

import { all, call } from "redux-saga/effects";

function* fetchAllData() {
  // Run multiple calls in parallel (array form)
  const [users, posts, comments] = yield all([
    call(fetchUsers),
    call(fetchPosts),
    call(fetchComments)
  ]);
  
  // Run with labels (object form)
  const { userData, profileData } = yield all({
    userData: call(fetchUser, userId),
    profileData: call(fetchProfile, userId)
  });
}

race

Creates an effect that runs a race between multiple effects. The first effect to complete wins, and all others are automatically cancelled.

/**
 * Run race between multiple effects, first to complete wins
 * @param effects - Object with labeled effects to race
 * @returns RaceEffect that resolves with winner's result
 */
function race<T>(effects: { [key: string]: T }): RaceEffect<T>;

/**
 * Race with array of effects
 * @param effects - Array of effects to race
 * @returns RaceEffect
 */
function race<T>(effects: T[]): RaceEffect<T>;

Usage Examples:

import { race, call, take, delay } from "redux-saga/effects";

function* fetchWithTimeout() {
  const { response, timeout } = yield race({
    response: call(fetchUser, userId),
    timeout: delay(5000, 'TIMEOUT')
  });
  
  if (timeout) {
    console.log('Request timed out');
  } else {
    console.log('Got response:', response);
  }
}

function* cancellableFetch() {
  const { data, cancelled } = yield race({
    data: call(fetchData),
    cancelled: take('CANCEL_FETCH')
  });
  
  if (cancelled) {
    console.log('Fetch was cancelled by user');
  }
}

setContext

Creates an effect that updates the saga's context. This extends the context rather than replacing it.

/**
 * Update saga's context (extends existing context)
 * @param props - Properties to add/update in context
 * @returns SetContextEffect
 */
function setContext<C extends object>(props: C): SetContextEffect<C>;

getContext

Creates an effect that returns a specific property of the saga's context.

/**
 * Get property from saga's context
 * @param prop - Property name to retrieve
 * @returns GetContextEffect that resolves with property value
 */
function getContext(prop: string): GetContextEffect;

Usage Examples:

import { setContext, getContext, call } from "redux-saga/effects";

function* apiSaga() {
  // Set context
  yield setContext({ 
    apiClient: new ApiClient(),
    userId: 123 
  });
  
  // Get from context
  const apiClient = yield getContext('apiClient');
  const userId = yield getContext('userId');
  
  const data = yield call([apiClient, 'fetchUser'], userId);
}

detach

Detaches a fork effect, making it run independently of its parent.

/**
 * Detach a fork effect from its parent
 * @param forkEffect - ForkEffect to detach
 * @returns Detached ForkEffect
 */
function detach(forkEffect: ForkEffect): ForkEffect;

Usage Examples:

import { fork, detach } from "redux-saga/effects";

function* parentSaga() {
  // Create detached fork
  yield detach(fork(backgroundService));
  
  // Parent can complete without waiting for detached task
}

Install with Tessl CLI

npx tessl i tessl/npm-redux-saga

docs

basic-effects.md

channels.md

concurrency-effects.md

helper-effects.md

index.md

middleware.md

testing.md

utilities.md

tile.json