Я использую redux-saga и имею следующий код:
function* loginFlow(username, password) {
try {
yield call(loginApi, username, password);
yield put({ type: LOGIN_SUCCESS });
yield put({ type: TOGGLE_LOGGED_DONE, payload: true });
yield put(push('/dashboard'));
} catch (error) {
yield put({ type: LOGIN_ERROR, error });
} finally {
if (yield cancelled()) {
console.log('ALWAYS CANCELLED');
// yield put(replace('/login'));
}
}
}
// Watcher saga.
function* loginWatcher() {
while (true) {
const { username, password } = yield take(LOGIN_REQUESTING);
const task = yield fork(loginFlow, username, password);
const action = yield take([LOGOUT, LOGIN_ERROR]);
if (action.type === LOGOUT) yield cancel(task);
yield call(logoutUser);
}
}
Проблема в том, что функция loginFlow
всегда отменяется (я вижу 'ALWAYS CANCELLED'
в консоли). Даже если я удалю const action = yield take([LOGOUT, LOGIN_ERROR]);
и yield call(logoutUser);
из loginWatcher
.
Я не вижу, чтобы либо LOGOUT
, либо LOGIN_ERROR
были уволены:
Есть идеи, что не так с моим кодом?
Обратите внимание, что я использую withRouter
в index.js для страницы входа, где выше сага (иначе я получаю пустой экран при перенаправлении):
const withSaga = injectSaga({ key: 'login', saga });
export default compose( withReducer, withSaga, withConnect, )(LoginPage);
С наилучшими пожеланиями
EDIT:
Если обернуть loginWatcher
в try/catch
, я также перейду к finally
там:
function* loginWatcher() {
while (true) {
try {
const { username, password } = yield take(LOGIN_REQUESTING);
const task = yield fork(loginFlow, username, password);
const action = yield take([LOGOUT, LOGIN_ERROR]);
if (action.type === LOGOUT) yield cancel(task);
yield call(logoutUser);
} catch (error) {
yield put({ type: LOGIN_ERROR, error });
} finally {
if (yield cancelled()) {
console.log('HERE AS WELL');
// yield put(push('/login'));
}
}
}
}