以下两种方法之间会有什么区别?
export function* watchLoginUser() {
yield takeEvery(USER_LOGIN, loginUser)
}
export function* watchLogoutUser() {
yield takeEvery(USER_LOGOUT, logoutUser)
}
export function* watchGetParties() {
yield takeEvery(PARTIES_GET, getParties)
}
export default function* root() {
yield [
fork(watchLoginUser),
fork(watchLogoutUser),
fork(watchGetParties)
]
}
export default function* root() {
yield [
takeEvery(USER_LOGIN, loginUser),
takeEvery(USER_LOGOUT, logoutUser),
takeEvery(PARTIES_GET, getParties)
]
}
我什么时候需要使用fork而不是?
答案 0 :(得分:54)
通常,当saga需要启动非阻塞任务时,fork
非常有用。此处的非阻塞意味着:调用者启动任务并继续执行而无需等待它完成。
在各种情况下,这可能很有用,但主要有两个:
您的顶级传奇可以作为第一个用例的示例。你可能会有类似的东西:
yield fork(authSaga);
yield fork(myDomainSpecificSaga);
// you could use here something like yield [];
// but it wouldn't make any difference here
authSaga
可能包括以下内容:
yield takeEvery(USER_REQUESTED_LOGIN, authenticateUser);
yield takeEvery(USER_REQUESTED_LOGOUT, logoutUser);
您可以看到此示例与您的建议相同,使用fork
调用一个产生takeEvery
调用的传奇。但实际上,您只需要为代码组织目的这样做。 takeEvery
本身就是一个分叉的任务,因此在大多数情况下,这将是无用的冗余。
第二个用例的例子如下:
yield take(USER_WAS_AUTHENTICATED);
const task = yield fork(monitorUserProfileUpdates);
yield take(USER_SIGNED_OUT);
yield cancel(task);
您可以在此示例中看到monitorUserProfileUpdates
将在调用者saga恢复时执行,并等待调度USER_SIGNED_OUT
操作。它还可以保留对它的引用,以便在需要时取消它。
为了完整起见,还有另一种方法可以启动非阻塞调用:spawn
。 fork
和spawn
在错误和取消从子级传播到父级传奇的过程中存在差异。
答案 1 :(得分:0)
通常 fork
在某些具有多次 API 调用分派的情况下变得更有用,原因是您可以通过实例化任务的取消来拒绝这些提取,例如cancel(task1);
如果最终用户强行退出应用程序或其中一项任务失败而导致您的指令、策略和逻辑出现问题并且取消或终止您的 saga 上的当前处理任务可能是合理的,则很有用;< /p>
有2种方式取消任务
来自 redux-saga Non-Blocking 效果取消的文档的基础
import { take, put, call, fork, cancel } from 'redux-saga/effects'
// ...
function* loginFlow() {
while (true) {
const {user, password} = yield take('LOGIN_REQUEST')
// Non-Blocking Effect which is the fork
const task = yield fork(authorize, user, password)
const action = yield take(['LOGOUT', 'LOGIN_ERROR'])
if (action.type === 'LOGOUT'){
//cancel the task
yield cancel(task)
yield call(Api.clearItem, 'token')
}
}
}
或
import {call, put, fork, delay} from 'redux-saga/effects';
import someAction from 'action/someAction';
function* fetchAll() {
yield fork(fetcher, 'users');
yield fork(fetcher, 'posts');
yield fork(fetcher, 'comments');
yield delay(1500);
}
function* fetcher(endpoint) {
const res = yield call(fetchAPI, endpoint);
if (!res.status) {
throw new Error(`Error: ${res.error}`);
}
yield put(someAction({payload: res.payload}));
}
function* worker() {
try {
yield call(fetchAll);
} catch (err) {
// handle fetchAll errors
}
}
function* watcher() {
yield takeEvery(BLOGS.PUSH, worker);
}
欢迎您:)