第二次调度动作时不会触发 Saga
Saga is not triggered the second time an action is dispatched
我正在尝试使用 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
使用 take
效果,saga 调用 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
};
...
}
};
我正在尝试使用 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
使用 take
效果,saga 调用 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
};
...
}
};