Как отменить все запущенные саги при переходе между просмотрами страниц

Я пытаюсь найти простой и легкий способ отменить все запущенные саги на «странице», когда пользователь решает перейти на другую «страницу» в приложении... Мы не используем маршрутизацию, а вместо этого каждую «страницу» это собственный виджет в более крупном хост-приложении, который отвечает за создание и загрузку каждой страницы при навигации пользователя...

В настоящее время мы используем redux-saga и имеем подобную логику настройки (упрощенную для краткости), когда виджет страницы создается и загружается...

// page-sagas
export function* rootSaga() {
  const allSagas = [
    // ... all sagas used by page (example) ...
    // function* watchFoo() {
    //   yield takeEvery(FooAction, foo);
    // }
  ];
  yield all(allSagas.map((saga) => call(saga)));
}

// page-widget
onLoad = () => {
  const sagaMiddleware = createSagaMiddleware();
  const store = createStore(reducer, initState, applyMiddlware(sagaMiddleware));
  sagaMiddleware.run(rootSaga);
}

В идеале я бы предпочел избежать необходимости добавлять логику разветвления в каждую отдельную сагу на каждом отдельном виджете страницы, и, глядя на API задач Redux-Saga, он говорит, что вы можете отменить задачу, возвращаемую вызовом middleware.run, но мне интересно, распространяется ли это на все вложенные/дочерние саги, которые в настоящее время выполняются, или есть ли какие-либо проблемы/ошибки, о которых я должен знать:

Пример:

// page-widget
onLoad = () => {
  ...
  this.task = sagaMiddlware.run(rootSaga);
}

destroy = () => {
  this.task.cancel();
}

person Joshua Barker    schedule 12.09.2019    source источник
comment
cancel остановит все дочерние саги от получения каких-либо дополнительных эффектов, но если у вас есть асинхронный код в полете (например), это не будет волшебным образом отменено... но поскольку вы больше не даете никаких эффектов, это не должно не влияет на состояние приложения.   -  person spender    schedule 12.09.2019
comment
@spender, просто чтобы уточнить, вы говорите, что это не отменит что-то вроде AJAX-запроса в полете, но остановит продолжение саги после того, как этот запрос вернется?   -  person Joshua Barker    schedule 12.09.2019
comment
Именно так, да.   -  person spender    schedule 12.09.2019
comment
Если вы хотите отменить запросы ajax в полете, для этого есть шаблоны, но, как уже упоминалось, это не происходит волшебным образом. Это требует сохранения ссылки на любой механизм, который у вас есть, чтобы отменить запрос, прежде чем yielding связанное обещание, а затем отменить в блоке if (yield cancelled()) в предложении finally, обертывающем выполнение запроса.   -  person azundo    schedule 12.09.2019
comment
@azundo да, меня не так беспокоит запрос в полете ... просто сага ... так что похоже, что это должно сработать ... спасибо всем!   -  person Joshua Barker    schedule 12.09.2019