我正在尝试使用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
答案 0 :(得分:2)
具有take
效果的传奇调用action = getNextAction()
将在分派动作时解决,因此您的searchUsersSaga
应该在while(true)
循环中。
还有一个问题,万一SEARCH_USERS_SUCCESS
,searchUsersSaga
等待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
};
...
}
};