免责声明:我是 redux-observable 的作者之一,所以我很难做到 100% 公正。
我们目前没有提供任何理由 redux-observable 比 redux-saga 更好,因为......它不是。
tl;博士两者都有优点和缺点。许多人会发现其中一个比另一个更直观,但是如果您不了解 RxJS(redux-observable)或生成器/“作为数据的效果”(redux-saga),那么两者都很难以不同的方式学习。
它们以极其相似的方式解决相同的问题,但有一些根本差异,只有在你充分使用它们后才会真正显现出来。
redux-observable 几乎将一切都推迟到惯用的 RxJS。所以如果你有 RxJS 知识(或获得它),学习和使用 redux-observable 是超级超级自然的。这也意味着这些知识可以转移到 redux 以外的东西上。如果您决定切换到 MobX,如果您决定切换到 Angular2,如果您决定切换到未来的热门 X,那么 RxJS 可以帮助您的机会非常好。这是因为 RxJS 是一个通用的异步库,在很多方面它本身就像一门编程语言——整个“反应式编程”范式。RxJS 自 2012 年以来就存在,并开始作为 Rx.NET 的一个端口(几乎所有主要语言都有“端口”,它很有用)。
redux-saga 自己提供了基于时间的操作符,因此虽然您在这种流程管理器样式中获得的有关生成器和处理副作用的知识是可以转移的,但实际的操作符和用法并未在任何其他主要库中使用。所以这有点不幸,但它本身肯定不应该成为交易破坏者。
它还使用“作为数据的效果”(在此处描述),一开始您可能很难理解,但这意味着您的 redux-saga 代码本身实际上并没有执行副作用。相反,您使用的辅助函数会创建类似于任务的对象,这些任务表示执行副作用的意图,然后内部库会为您执行它。这使得测试变得非常容易,无需模拟,并且对某些人非常有吸引力。但是,我个人发现这意味着您的单元测试重新实现了您传奇的大部分逻辑 - 使这些测试不是很有用 IMO(这种观点并非所有人都同意)
人们经常问为什么我们不对 redux-observable 做类似的事情:对我来说,它与普通的惯用 Rx 根本不兼容。在 Rx 中,我们使用这样的运算符.debounceTime()
来封装去抖动所需的逻辑,但这意味着如果我们想要创建一个不实际执行去抖动的版本,而是根据意图发出任务对象,你现在已经失去了Rx 的强大功能,因为您不能再将操作符链接起来,因为它们将在该任务对象上进行操作,而不是操作的实际结果。这真的很难优雅地解释。它再次需要对 Rx 有深入的了解才能理解方法的不兼容性。如果你真的想要这样的东西,请查看redux-cycles它使用 cycle.js 并且主要有这些目标。我发现这对我的口味来说需要太多的仪式,但如果你感兴趣,我鼓励你试一试。
正如 ThorbenA 所提到的,我并不回避承认 redux-saga 目前(10/13/16)是 redux 复杂副作用管理的明确领导者。它起步较早,并且拥有更强大的社区。因此,使用事实上的标准对街区的新孩子有很大的吸引力。我认为可以肯定地说,如果您在没有先验知识的情况下使用其中任何一种,您就会感到困惑。我们都使用了相当先进的概念,一旦你“掌握”,就会使复杂的副作用管理变得容易得多,但在那之前,很多人都会绊倒。
我能给出的最重要的建议是在你需要它们之前不要引入这些库中的任何一个。如果您只是进行简单的 ajax 调用,您可能不需要它们。redux-thunk 简单易学,并且为基础知识提供了足够的能力——但异步越复杂,redux-thunk 就越难(甚至不可能)。但是对于 redux-observable/saga 在许多方面它最闪耀,异步越复杂。在同一个项目中将 redux-thunk 与其他一个(redux-observable/saga)一起使用也有很多优点!redux-thunk 用于常见的简单内容,然后仅将 redux-observable/saga 用于复杂的内容。这是保持生产力的好方法,所以你不会为了那些对 redux-thunk 微不足道的事情而与 redux-observable/saga 抗争。