redux-saga项目已经存在很长时间了,但是这个库仍然有很多令人困惑的事情.其中一个是:如何开始你的rootSaga.例如,在初学者教程中, rootSaga是通过一系列传奇来启动的.像这样
export default function* rootSaga() {
yield [
helloSaga(),
watchIncrementAsync()
]
}
Run Code Online (Sandbox Code Playgroud)
然而,在使用传奇助手部分,rootSaga由两个分叉的传奇组成.像这样:
export default function* rootSaga() {
yield fork(watchFetchUsers)
yield fork(watchCreateUser)
}
Run Code Online (Sandbox Code Playgroud)
在redux-saga repo中的异步示例中使用了与启动rootSaga相同的方法.但是,如果你查看真实世界和购物卡的例子,你会看到rootSagas那里有一系列分叉的传奇.像这样:
export default function* root() {
yield [
fork(getAllProducts),
fork(watchGetProducts),
fork(watchCheckout)
]
}
Run Code Online (Sandbox Code Playgroud)
另外,如果您在redux-saga问题中阅读了一些讨论,您会看到有些人建议使用spawn而不是fork来为rootSaga保护应用程序完全崩溃,如果您的某个分叉传奇由于某些未处理的异常而被取消.
那么,哪种方式是启动rootSaga的最正确的方法?现有的有什么区别?
Seb*_*ber 14
你可以开始多根传奇.但是任何传奇都有能力自己创造另一个传奇.因此,有可能开始一个单根传奇,创造另一个传奇.
您只需要知道错误如何传播到父级传奇.如果你有一个根传奇和一个子传奇崩溃,默认情况下,错误将传播到将终止的父级,这也将杀死从这个父级启动的所有其他传奇.
由您来决定这种行为.根据您的应用程序,你可能希望有一个快速失败行为(使整个应用程序无法使用,如果有这样的问题),或故障安全,并尽量使应用程序继续工作,即使如果某些部分可能有问题.
一般来说,我建议您启动多个根传奇,或者您的父传奇使用spawn
而不是fork
使您的应用程序在发生崩溃时仍然可用.请注意,在某些地方忘记捕获错误也很容易.例如,如果单个API请求失败,您通常不希望所有应用都变得无法使用
编辑:我建议你看看https://github.com/yelouafi/redux-saga/issues/570
在这个redux-saga问题中,我展示了启动传奇的不同方法及其对您的应用程序的影响.
TLDR:这就是我通常开始根源传奇的方式:
const makeRestartable = (saga) => {
return function* () {
yield spawn(function* () {
while (true) {
try {
yield call(saga);
console.error("unexpected root saga termination. The root sagas are supposed to be sagas that live during the whole app lifetime!",saga);
} catch (e) {
console.error("Saga error, the saga will be restarted",e);
}
yield delay(1000); // Workaround to avoid infinite error loops
}
})
};
};
const rootSagas = [
domain1saga,
domain2saga,
domain3saga,
].map(makeRestartable);
export default function* root() {
yield rootSagas.map(saga => call(saga));
}
Run Code Online (Sandbox Code Playgroud)
np8*_*np8 14
据的终极版,佐贺芯显影剂[1 ,2]以创建rootSaga惯用的方法是使用在所有效应Combinator的.此外,请注意,不推荐使用来自sagas的数组.
你可以使用像这样(+全)
import { fork, all } from 'redux-saga/effects';
import firstSaga from './firstSaga';
import secondSaga from './secondSaga';
import thirdSaga from './thirdSaga';
export default function* rootSaga() {
yield all([
fork(firstSaga),
fork(secondSaga),
fork(thirdSaga),
]);
}
Run Code Online (Sandbox Code Playgroud)
// foo.js
import { takeEvery } from 'redux-saga/effects';
export const fooSagas = [
takeEvery("FOO_A", fooASaga),
takeEvery("FOO_B", fooBSaga),
]
// bar.js
import { takeEvery } from 'redux-saga/effects';
export const barSagas = [
takeEvery("BAR_A", barASaga),
takeEvery("BAR_B", barBSaga),
];
// index.js
import { fooSagas } from './foo';
import { barSagas } from './bar';
export default function* rootSaga() {
yield all([
...fooSagas,
...barSagas
])
}
Run Code Online (Sandbox Code Playgroud)
fork和spawn都将返回Task对象.分叉任务附加到父级,而生成的任务与父级分离.
叉子中的错误处理[ link ]:
子任务的错误会自动冒泡到父母身上.如果任何分叉的任务引发了未被捕获的错误,那么父任务将以 子Error中止,并且整个Parent的执行树 (即分叉任务+父项主体表示的主要任务,如果它仍在运行)将被取消.
生成任务中的错误处理[ link ]:
在返回之前,父级不会等待分离的任务终止,并且可能影响父级或分离的任务的所有事件都是完全独立的(错误,取消).
基于上面,您可以使用fork来执行"关键任务"任务,即 "如果此任务失败,请崩溃整个应用程序",并为"非关键"任务生成,即 "如果此任务失败,请不要传播父母的错误".
归档时间: |
|
查看次数: |
6489 次 |
最近记录: |