佐贺总是被取消

时间:2018-11-09 10:27:32

标签: redux-saga

我使用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

我看不到LOGOUTLOGIN_ERROR被解雇了: Redux devtools output

任何想法我的代码有什么问题吗?

请注意,我在index.js的登录页面中使用了withRouter,上面的传奇故事就出现了(否则我在重定向时会出现黑屏):

const withSaga = injectSaga({ key: 'login', saga }); 

export default compose( withReducer, withSaga, withConnect, )(LoginPage); 

最好的问候

编辑: 如果将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'));
      }
    }
  }
}

1 个答案:

答案 0 :(得分:1)

我将发布我们收集的内容作为答案,以便该问题对将来的读者有用。

在redux-saga中,通过call()fork()开始的sagas被递归取消。 Saga 表示可递归取消的任务。因此,当某个传奇被取消后,您应该检查其父传奇,依此类推。

您发布的此代码段:

const withSaga = injectSaga({ key: 'login', saga });
export default compose( withReducer, withSaga, withConnect, )(LoginPage)

Google建议使用this redux-saga + react-boilerplate example。它涵盖取消以及如何禁用它。检查链接以找到有关它的信息。

我不熟悉react-boilerplate(反应生态系统很大),但是我想我的回答至少会缩小搜索范围。如果您感到困惑,请考虑与提出另一个问题。