Skip to content

Cancelling in-flight fetch requests with AbortController/AbortSignal #1917

@slorber

Description

@slorber

Hey, for a blog post I'm working on about race conditions, where I mention takeLatest, I was wondering how we could add support for in-flight request cancellations to Redux-saga in a generic way.

My saga is a bit rusty, but I wrote this pseudo code.

function withAbortSignal(generator) {
  return function* abortableGenerator(...args) {
    let abortController = new AbortController();
    try {
      yield * generator(abortController.signal, ...args);
    } finally {
      if (yield cancelled()) {
        abortController.abort();
      }
    }
  }
}

function* loadStarwarsHeroSaga() {
  yield* takeLatest('LOAD_STARWARS_HERO', withAbortSignal(function* loadStarwarsHero(signal,action) {
    try {
      const hero = yield fetch(`http://data.com/${action.payload.id}`, {signal});
      yield put({ type: 'LOAD_STARWARS_HERO_SUCCESS', hero });
    } catch (err) {
      yield put({ type: 'LOAD_STARWARS_HERO_FAILURE', err });
    }
  });
}

What do you think about supporting officially some helpers for in-flight request cancellation?

Note redux-observable/rxjs already has some more advanced discussions/implementations regarding this feature: ReactiveX/rxjs#3122

https://github.com/ReactiveX/rxjs/blob/1dc09e9f21780645063407d6670ee2f5e3e399f5/src/internal/observable/dom/fetch.ts

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions