Я пытаюсь найти простой и легкий способ отменить все запущенные саги на «странице», когда пользователь решает перейти на другую «страницу» в приложении... Мы не используем маршрутизацию, а вместо этого каждую «страницу» это собственный виджет в более крупном хост-приложении, который отвечает за создание и загрузку каждой страницы при навигации пользователя...
В настоящее время мы используем 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();
}
cancel
остановит все дочерние саги от получения каких-либо дополнительных эффектов, но если у вас есть асинхронный код в полете (например), это не будет волшебным образом отменено... но поскольку вы больше не даете никаких эффектов, это не должно не влияет на состояние приложения. - person spender   schedule 12.09.2019yield
ing связанное обещание, а затем отменить в блокеif (yield cancelled())
в предложенииfinally
, обертывающем выполнение запроса. - person azundo   schedule 12.09.2019