5

我使用 redux-saga 的主要原因之一是它进行异步函数调用的可测试性。我的困境是,当我使用不属于我的 redux 存储的有状态对象进行编程时,使用 sagas 进行编程变得非常尴尬。是否有使用非纯数据对象和 redux-saga 的最佳实践?

假设我有在 API 中注册的回调函数,在这种情况下是 firebase,我需要保留这些回调函数,以便以后取消注册。我无法将这些回调函数存储在 redux 中,那么将其写成 saga 还有意义吗?

在一段代码中似乎有点奇怪,以便能够使用诸如 put、select 之类的东西,而在其他代码中我必须使用 store.dispatch。

例子:

  const childAddedTrigger = (dataSnapshot: firebase.database.DataSnapshot) => {
    const message = Object.assign({}, dataSnapshot.val(), {
      key: dataSnapshot.key,
    });
    service.store.dispatch(Actions.channelMessageAdded(channelId, message));
  }    

  service.firebase.database().ref(`channels/${channelId}/messages`)
    .limitToLast(20)
    .on('child_added', childAddedTrigger);

  this.channelSubscriptions[channelId] = childAddedTrigger;
4

2 回答 2

6

你会想要使用Channels的 redux-saga 概念。

这样的效果take, call, put使得异步函数很容易使用 redux-saga 进行测试,默认情况下会与 redux 的 store 交互,因为该库首先是一个 redux 中间件。

但是,eventChannel工厂函数允许您从 websocket 或 firebase 获取外部事件源并从它们“获取”事件,而不是从存储中分派操作并将事件“放置”到它们,而不是到 redux 存储。

于 2016-08-25T00:32:41.160 回答
3

你想要的是runSaga. 它是通过将 saga 所需的一切作为参数来运行任何 saga 的函数。

正如@TheBrofessor 所说,由于redux-saga 通过与一些输入和输出进行通信来工作,如果你可以定义这样的输入和输出,它就可以在redux-saga 中运行。channeloption 和optiondispatch负责为 saga 提供输入和输出。有关详细说明,请参阅文档。

需要注意的一件事(文档中没有记录)是stdChannel. 实际上,Channel 文档中描述的通道的行为类似于队列。其中的行为stdChannel是订阅/调度(就像任何其他订阅框架中的“频道”一样)。

这是因为它stdChannel是一个特殊的频道,其行为类似于订阅频道。实际上,redux-saga 连接到 redux store 时,会将 store 的所有 dispatch events 放入stdChannel中,所以每一个正在takeing 的 saga 都可以接收到 dispatch event。

你可以确认 redux-saga 实际上multicast 在他们的源代码中定义了 of 的概念,它是在stdChannel.

于 2019-10-19T04:08:58.010 回答