为什么使用可观察的复制版而不是复制传奇?

我用过 终极传奇。到目前为止,用它编写的代码很容易推理,除了 JS 生成器函数时不时地把我搞糊涂之外。根据我的理解,重现-可观察可以实现类似的工作,处理副作用,但不使用生成器功能。

然而,来自 Redux-Observer 的文档并没有提供很多关于为什么它优于 Redux-Saga 的意见。我想知道不使用生成器函数是否是使用 Redux-Observer 的唯一好处。使用可观察的 Redux 而不是使用传奇的 Redux 会有什么不好的地方?

42062 次浏览

我使用可观察的 Redux 而不是 Redux-Saga,因为我更喜欢使用可观察的而不是生成器。我将它与 RXJS 一起使用,RXJS 是一个强大的数据流库。可以把它想象成异步的 loash。关于任何不利因素,在选择其中一个方面遇到的困难和妥协,让我们来看看杰伊 · 菲尔普斯的 这个答案:

Redux-saga 作为一个项目已经存在的时间比 redux-观察到的时间要长,所以这当然是一个主要的卖点。您将发现更多的文档、示例,并且可能有更好的社区来提供支持。

相反,您在 redux-saga 中学到的操作符和 API 并不像学习 RxJS 那样具有可转换性,RxJS 被广泛使用。Redux-Observer 在内部是超级超级超级简单的,它实际上只是为您提供了一种使用 RxJS 的自然方法。因此,如果您知道 RxJS (或者想知道) ,那么它是一个非常自然的匹配。

目前,我给大多数人的建议是,如果你必须问自己应该使用哪一个,你可能应该选择 redux-saga。

免责声明: 我是 reduc- 观察的作者之一,所以对我来说很难做到100% 的公正。

我们目前没有提供任何理由说明可观察到的复原比复原传奇更好,因为... 它不是。

两者都有利有弊。许多人会发现其中一个比另一个更直观,但是如果你不知道 RxJS (可观察的还原)或者生成器/“效果作为数据”(可观察的还原) ,两者都是以不同的方式学习的复杂的。

它们以极其相似的方式解决同样的问题,但是有一些基本的差异,只有当你使用得足够多时,这些差异才会变得真正明显。

Redux-Observer 将几乎所有内容都延迟到惯用的 RxJS。因此,如果您有 RxJS 知识(或者获得它) ,学习和使用 redux-Observer 是非常自然的。这也意味着这个知识可以转移到除了还原以外的事物上。如果您决定切换到 MobX,如果您决定切换到 Angular2,如果您决定切换到一些未来的热点 X,机会是非常好的,RxJS 可以帮助您。这是因为 RxJS 是一个通用的异步库,在很多方面它本身就像一种编程语言ーー整个“响应式编程”范式。RxJS 从2012年开始存在,最初是作为 Rx.NET 的一个端口(几乎每种主要语言都有“端口”,它是 那么有用)。

Redux-saga 本身提供了基于时间的操作符,因此,尽管您获得的关于生成器和处理流程管理器风格中的副作用的知识是可转移的,但实际的操作符和用法并没有在任何其他主要库中使用。所以这是有点不幸,但肯定不应该是一个交易破坏本身。

它还使用“效果作为数据”(这里描述的) ,一开始可能很难理解,但这意味着你的 redux-saga 代码实际上并不执行副作用本身。相反,您使用的 helper 函数创建的对象类似于表示执行副作用的意图的任务,然后内部库为您执行这些任务。这使得测试非常容易,不需要嘲笑,并且对某些人非常有吸引力。然而,我个人发现这意味着您的单元测试重新实现了您的长篇故事的大部分逻辑——使得这些测试不是非常有用的 IMO (这个观点并不是每个人都同意的)

人们经常问我们为什么不用 redux-Observer 做这样的事情: 对我来说,它根本不符合正常的惯用语 Rx。在 Rx 中,我们使用像 .debounceTime()这样的操作符来封装去除操作所需的逻辑,但是这意味着如果我们想要创建一个不实际执行去除操作的版本,而是有意地发出任务对象,那么现在就失去了 Rx 的能力,因为你不能再仅仅使用链操作符了,因为它们将操作那个任务对象,而不是操作的真正结果。这真的很难解释清楚。同样需要对 Rx 有深入的了解,以理解各种方法的不兼容性。如果您想要类似的东西,请查看 还原循环,它使用 cycle.js,并且大部分都具有这些目标。我发现对于我的品味来说,它需要太多的仪式,但是如果你感兴趣的话,我鼓励你尝试一下。

正如 ThorbenA 提到的,我并不回避承认,目前(10/13/16)在复杂的副作用管理复发的明确领导者。它起步较早,并且有一个更加强大的社区。所以用行业标准对付新来的孩子很有吸引力。我想可以肯定地说,如果你在没有事先知情的情况下使用其中任何一种,你都会陷入困惑。我们都使用相当先进的概念,一旦你“得到”,使复杂的副作用管理容易得多,但在那之前,许多人都犯了错误。

我能给出的最重要的建议是,在您需要这些库之前,不要使用它们中的任何一个。如果您只是使用简单的 ajax 调用,则可能不需要它们。Redux-thunk 学起来很简单,并且提供了足够的基础知识——但是异步越复杂,redux-thunk 就变得越难(甚至不可能)。但是对于可以观察到的 redux/saga 来说,异步越复杂,它在许多方面的表现就越出色。在同一个项目中使用 redux-thunk 和其他的一个(redux-Observer/saga)也有很多优点!对于你常见的简单的东西使用 redux-thunk,然后对于复杂的东西只使用 redux-Observer/saga。这是一个保持生产力的好方法,所以你不会为了一些微不足道的事情而与可观察到的还原/传奇战斗。

我觉得有些事情你需要考虑一下。

  1. 复杂性
  2. 编码风格
  3. 学习曲线
  4. 可测试性

假设我们想从 API 获取用户

// Redux-Saga


import axios from 'axios'


function* watchSaga(){
yield takeEvery('fetch_user', fetchUser) // waiting for action (fetch_user)
}


function* fetchUser(action){
try {
yield put({type:'fetch_user_ing'})
const response = yield call(axios.get,'/api/users/1')
yield put({type:'fetch_user_done',user:response.data})
} catch (error) {
yield put({type:'fetch_user_error',error})
}
}


// Redux-Observable
import axios from 'axios'


const fetchUserEpic = action$ =>
action$
.ofType('fetch_user')
.flatMap(()=>
Observable.from(axios.get('/api/users/1')) // or use Observable.ajax
.map(response=>({type:'fetch_user_done', user:response.data}))
.catch(error => Observable.of({type:'fetch_user_error',error}))
.startWith({type:'fetch_user_ing'})
)

此外,我写这篇文章是为了比较 Redux-saga 和 Redux-Observer 之间的深度差异。检查 这里的链接展示

我重视 Rx 所具有的跨语言和运行时的可转移性。即使你的应用程序不会改变语言,你的职业生涯可能会。无论你自己如何衡量,都要在学习过程中获得最佳的杠杆作用。这是通往。特别是 Net LINQ。

Redux-Observer 是一个了不起的库,我们在生产环境中使用它已经1.5年了,到目前为止没有任何问题,它完全可以测试,并且可以很容易地与任何框架集成。我们有极端超载的并行套接字通道和唯一的事情是从冻结拯救我们是可观察的 Redux

我有三点想在这里提一下。

1. 复杂性和学习曲线

在这里,复制传奇轻易地击败了可以观察到的复制传奇。如果您只需要一个简单的请求来完成授权,并且由于某些原因不想使用 redux-thunk,那么您应该考虑使用 redux-saga,因为它更容易理解。

如果你没有事先了解观察,这将是一个痛苦,你和你的团队将课程你:)

2. Observer 和 RxJS 能为我提供什么?

当涉及到异步逻辑时,可观察的是你的瑞士刀,可观察的几乎可以为你做任何事情。你永远不应该把它们和承诺或发电机相比它们的功率要大得多,就像把擎天柱和雪佛兰相比一样。

那 RxJS 呢?它类似于 lodash.js,但是对于异步逻辑,一旦进入其中,您将永远不会切换到不同的东西。

3. 反应性延伸

看看这个链接

Http://reactivex.io/languages.html

反应式扩展是为所有现代编程语言实现的,它只是函数式编程的关键。

因此,明智地利用你的时间学习 RxJS,并使用 redux-Observer:)

既然这里有一大堆可以简单观察到的话题,我想我应该从长篇故事的角度来讨论这个问题。我不使用 redux-Observer 或 RxJS,所以我不能给出并列比较,但是我使用了传奇效果很好。

不管怎样,我正在一个 Web 应用程序的生产环境中使用传奇故事。

传奇对桑克

传奇轻而易举就赢了。我不喜欢 Thunk 把逻辑放进我的动作创造者里。它还使得连续执行几个请求变得很麻烦。我简单地看了一下这份工作的简历,但最终选择了传奇。

传奇故事的学习曲线

理解什么是生成器以及它们为什么重要是理解传奇的关键。但我要强调的是,你们 不要需要了解发电机的内部和外部。您只需要知道您正在通过屈服语句传递控制权,并且在异步代码解析之后,传奇将传递回控制权。在那之后,就不难理解一个传奇故事中发生了什么。

根据我的经验,传奇故事的核心方法是:

  • call-调用任意位代码并获取返回值。支持承诺。异步处理和传奇之间的巨大协同作用。
  • 调用一个选择器。这一点是相当辉煌的。选择器的核心还原,他们是100% 的支持!
  • put-又名 dispatch一个行动。事实上,发送多少你想要的!

还有其他的功能,但是如果你能掌握这三个,你会处于一个非常好的位置。

结论

我之所以选择传奇故事,是因为它易于使用。看起来像是个挑战。我对传奇百分百满意。比我想象的还要开心。

根据我的经验,传奇故事比传奇故事要好得多,而且相对容易理解。处方不是每个人都喜欢的。如果你不是来自那个生态系统或者不打算在将来使用 Rx,我会强烈地考虑传奇而不是 reduc- 观察。

如果您使用 Typecript 编写应用程序,我建议您检查 没有类型。 它的灵感来自于 Redux-Observer,也依赖于 RxJS,但是构建这个应用程序有完整的生态系统。

最大的缺点是缺乏指导方针。关于如何减轻懒惰负载,传奇或史诗并没有官方的指导方针。在扩展更大的应用程序时,代码分割是至关重要的。 用于延迟加载的自定义解决方案通常不适用于导致开发人员体验差的 HMR。

无类型优点:

  1. 为 TypeScript 设计
    所有 API 都是为打印和类型安全而设计的:
    • 打字稿会提高你的工作效率,而不是减慢你的速度。
    • 只需要必要的注释: state、 action 参数。
    • 没有类型转换。一切都是自动推断的。95% 的代码看起来像纯 javascript。
    • 无 RootAction,RootEpic,RootState 或其他辅助类型。
  2. 提供所有组件
    • 类型包括一切构建中型或企业级应用程序。
    • 您不需要依赖于多个小型库。
  3. 模块化
    • 适当的模块化对于构建可伸缩的应用程序至关重要。
    • 不需要为 Epics、 reducers、 type 等创建根文件。创建新模块后,可以从任何位置附加它。类似于标准的反应组件。
  4. 固执己见
    • 所有常见的用例和问题都在默认情况下得到解决,不需要过多考虑如何修复琐碎的问题。
    • 提供了所有的建议和最佳实践!

看看 https://typeless.js.org/