启动rootSaga的惯用方式是什么? [英] What is the idiomatic way of starting rootSaga?

查看:65
本文介绍了启动rootSaga的惯用方式是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

redux-saga 项目已经存在很长时间了,但是关于这个库仍然有很多令人困惑的事情.其中之一是:如何启动您的 rootSaga.例如,在 初学者教程中,rootSaga 是通过 yeilding saga 数组启动的.像这样

redux-saga project has been existing for a pretty long time now, but still there are a lot of confusing things about this library. And one of them is: how to start your rootSaga. For example, in the beginner tutorial rootSaga is started by yeilding an array of sagas. Like this

export default function* rootSaga() {
  yield [
    helloSaga(),
    watchIncrementAsync()
  ]
}

然而,在 使用 saga helpers 部分中,rootSaga 包含两个分叉的 saga.像这样:

However, in the using saga helpers section rootSaga consists of two forked sagas. Like this:

export default function* rootSaga() {
  yield fork(watchFetchUsers)
  yield fork(watchCreateUser)
}

在 redux-saga repo 中的异步示例中使用了相同的启动 rootSaga 的方式.但是,如果您查看真实世界和购物卡示例,您会看到那里的 rootSagas 产生了一系列分叉的 saga.像这样:

The same way of starting rootSaga is used in async example in redux-saga repo. However, if you check real-world and shopping-card examples, you'll see that rootSagas there yeild an array of forked sagas. Like this:

export default function* root() {
  yield [
    fork(getAllProducts),
    fork(watchGetProducts),
    fork(watchCheckout)
  ]
}

此外,如果您阅读 redux-saga 问题中的一些讨论,您会发现有些人建议使用 spawn 而不是 fork for rootSaga 来保护您的应用程序,如果您的一个 fork saga 由于某些原因被取消,则不会完全崩溃未处理的异常.

Also, if you read some discussions in redux-saga issues, you'll see that some people suggest to use spawn instead of fork for rootSaga to guard you application from complete crashing if one of your forked sagas is canceled because of some unhandled exception.

那么,哪种方式最适合启动您的 rootSaga?现有的有什么区别?

So, which way is the most right way to start your rootSaga? And what are the differences between the existing ones?

推荐答案

您可以启动多个 root 传奇.但是任何传奇都有能力自己开始另一个传奇.因此,可以启动一个单独的根 saga,从而创建其他 saga.

You can start multiple root sagas. But any saga has the ability to start another saga on its own. Thus it's possible to start a single root saga, that creates the other sagas.

您只需要了解错误如何传播到父 saga.如果你有一个单一的 root saga 并且一个 child saga 崩溃了,默认情况下,错误将传播到将终止的父级,这也会杀死从这个父级开始的所有其他 saga.

You just need to be aware of how errors propagate to the parent saga. If you have a single root saga and a child saga crashed, by default the error will propagate to the parent which will terminate, which will also kill all the other sagas started from this parent.

此行为由您决定.根据您的应用程序,您可能想要快速失败行为(如果出现此类问题,则使整个应用程序无法使用),或失败安全,并尝试使应用程序继续工作,即使某些部分可能出现问题.

It's up to you to decide this behavior. According to your application you may want to have a fail fast behavior (make the whole app unusable if there's such a problem), or fail safe, and try to make the app continue working even if some parts may have problems.

通常,我建议您启动多个 root saga,或者您的父 saga 使用 spawn 而不是 fork,以便您的应用程序在发生崩溃时仍然可用.请注意,忘记捕捉某些地方的错误也很容易.例如,如果有一个 API 请求失败,您通常不希望您的所有应用程序都无法使用

Generally I'd recommend that you start multiple root sagas, or your parent saga uses spawn instead of fork so that your app remains usable if there's a crash. Note that it's also quite easy to forget to catch errors in some places. You generally don't want, for example, to have all your app become unusable if there's a single API request that fails

编辑:我建议看一下 https://github.com/yelouafi/redux-saga/issues/570

在这个 redux-saga 问题中,我展示启动 saga 的不同方式及其对您的应用程序的影响.

In this redux-saga issue, I show different ways to start sagas and the impact it has on your application.

TLDR:这就是我通常开始 root 传奇的方式:

TLDR: this is how I usually start root sagas:

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));
}

这篇关于启动rootSaga的惯用方式是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆