第二次发送动作时未触发佐贺

时间:2020-10-10 09:29:26

标签: reactjs react-redux redux-saga

我正在尝试使用redux-saga实现取消任务效果。它可以在第一次发送时运行良好,但是在第二次发送时,它什么也没做。传奇故事似乎已经结束或发生了什么。这是我的代码:

import { all, put, fork, take, cancel, cancelled } from "redux-saga/effects";

const searchUsers = function* () {
  try {
    yield new Promise((resolve) => setTimeout(resolve, 1500));
    const users = ["Bill Gates"];
    yield put({ type: "SEARCH_USERS_SUCCESS", users });
  } catch (e) {
    // log error
  } finally {
    if (yield cancelled()) {
      console.log("search was cancelled");
    }
  }
};

const searchUsersSaga = function* () {
  const searchAction = yield take("SEARCH_USERS");
  const searchTask = yield fork(searchUsers, searchAction.query);
  const cancleAction = yield take("SEARCH_USERS_CANCEL");

  if (cancleAction.type === "SEARCH_USERS_CANCEL") {
    yield cancel(searchTask);
  }
};

const rootSaga = function* saga() {
  yield all([searchUsersSaga].map(fork));
};

export default rootSaga;

我在此处创建了完整的代码:https://codesandbox.io/s/new-fast-snhr0?file=/src/index.js

1 个答案:

答案 0 :(得分:2)

具有take效果的传奇调用action = getNextAction()将在分派动作时解决,因此您的searchUsersSaga应该在while(true)循环中。

还有一个问题,万一SEARCH_USERS_SUCCESSsearchUsersSaga等待SEARCH_USERS_CANCEL,并且它也可能阻塞流,您应该分派另一个操作来处​​理这种情况。

const searchUsers = function* () {
  try {
    yield new Promise((resolve) => setTimeout(resolve, 1500));
    const users = ["Bill Gates"];
    yield put({ type: "SEARCH_USERS_SUCCESS", users });
  } catch (e) {
    // log error
  } finally {
    yield put({ type: "SEARCH_USERS_END" });
    if (yield cancelled()) {
      console.log("search was cancelled");
    }
  }
};

const searchUsersSaga = function* () {
  while (true) {
    const searchAction = yield take("SEARCH_USERS");
    const searchTask = yield fork(searchUsers, searchAction.query);
    const cancleAction = yield take([
      "SEARCH_USERS_CANCEL",
      "SEARCH_USERS_END"
    ]);

    if (cancleAction.type === "SEARCH_USERS_CANCEL") {
      yield cancel(searchTask);
    }
  }
};
export const usersReducer = (state = initialState, action) => {
  switch (action.type) {
    ...
    case "SEARCH_USERS_END":
      return {
        ...state,
        isSearching: false
      };
    ...
  }
};

https://codesandbox.io/s/sad-cori-yodq0