javascript - 使用 redux-saga 处理大量事件的订阅/取消订阅

标签 javascript reactjs redux redux-saga saga

在我当前的项目中,我正在处理 Firebase Websocket 订阅。不同的组件可以订阅不同的数据,例如在项目列表中,每个 ListItem 组件通过在 componentDidMount 中分派(dispatch) SUBSCRIBE 操作来订阅该特定项目的 websocket“事件”,并取消订阅在 componentWillUnmount 中调度 UNSUBSCRIBE 操作。

我的传奇是这样的:

const subscriptions = {}

export function * subscribeLoop () {
  while (true) {
    const { path } = yield take(SUBSCRIBE)
    subscriptions[path] = yield fork(subscription, path)
  }
}

export function * unsubscribeLoop () {
  while (true) {
    const { path } = yield take(UNSUBSCRIBE)
    yield cancel(subscriptions[path])
  }
}

export function * subscription (path) {
  let ref

  try {
    const updateChannel = channel()

    ref = api.child(path)
    ref.on('value', snapshot => {
      updateChannel.put(snapshot.val())
    })

    while (true) {
      const data = yield take(updateChannel)
      yield put(handleUpdate(path, data))
    }
  } finally {
    if (yield cancelled()) {
      ref.off()
      ref = null
    }
  }
}

我认为这不是处理这个问题的正确方法 - 对于 500 个项目的列表来说,它确实相当慢。

如何优化性能?

  • 我还需要 fork 吗?
  • 我应该引入某种延迟来给线程一些空间来处理其他事情吗?

任何提示表示赞赏。

最佳答案

Should i introduce some kind of delay to give the thread some space > to handle other things?

首先,有必要记住,使用 redux saga 和 fork 等效果实际上不会创建任何会在无限循环中扭曲的线程。它只是用于组织回调链的语法糖,因为yield 运算符在两侧提供对象传递。从这个 Angular 来看,强制延迟的问题没有意义——因为线程并不存在。

Do i even need to fork?

如果具备适当的技能,通常可以在没有一组调用 fork 的情况下完成任务,并在一个根传奇中完成所有操作。这个想法是在 websocket 上的当前词法区域中使用回调函数进行订阅,并期望在延迟 promise 的基础上在伪无限循环中获取消息。

从概念上讲,代码大致如下:

const subscribers = new Map()

function * webSocketLoop() {
  let resolver = null
  let promise = new Promise(resolve => (resolver = resolve))
  let message = null;

  websocket.on('message', (payload) => {
    message = Object.assign({}, payload)
    resolver()
    promise = promise.then(() => new Promise(resolve => (resolver = resolve)))
  })

  while(true) {
    yield call(() => promise)
    const type = message.type
    const handlers = subscribers.get(type) || []
    handlers.forEach(func => func(message))
  }
}

export function * mainSaga () {
  yield takeEvery(SUBSCRIBE, subscribe)
  yield takeEvery(UNSUBSCRIBE, unsubscribe)
  yield fork(webSocketLoop)
}

关于javascript - 使用 redux-saga 处理大量事件的订阅/取消订阅,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43603913/

相关文章:

javascript - 使用JavaScript push解析JSON数据——想防止自动关闭div

javascript - React-redux 状态和 Prop 已更新但组件未重新渲染

javascript - 如何从无渲染类 React-Native 调用函数

javascript - 在组件中作为 prop 访问调度函数

javascript - React Native - 不变违规 "RNDateTimePicker"

javascript - 检索 DIV 的 id 失败

javascript - 如何每 x 秒更改一次 Bootstrap 头图像?

javascript - 数组中的字符串 "</script>"被解释,是否有解决方法?

node.js - Set-Cookie header 中的 Cookie 未设置

javascript - 在构造函数之外实例化的 ES6+ 实例属性