redux saga,有条件地进行油门/反跳吗?

时间:2018-10-15 11:16:59

标签: redux-saga

我正在记录横幅在屏幕上可见的印象。

当用户滚动时,可以在短时间内多次显示同一横幅。

我想防止这种情况。

首先想到的是,throttle是防止它发生的完美方法。

但是如果您在一个页面中有多个横幅,throttle如果受到限制,将不会在屏幕上记录第二个横幅。

那么我该如何调节每个键? (在此示例中,横幅ID为键) 即,我想限制每个banner_id的横幅展示次数。 (就像服务器通过api键限制api_endpoint访问)

编辑

人们可以考虑为每个密钥创建throttle,但是想知道它是否会占用太多资源吗?

我想知道Django-rest-framework之类的API库如何实现每个api键的节流。我想这可能与传奇的节流阀完全不同。

1 个答案:

答案 0 :(得分:1)

使用有效的地图

诸如django-rest之类的东西会使用过期地图进行限制。有效的 set 也足以完成任务。

不幸的是,我无法为可用的地图/设置推荐确切的npm模块。

伪代码

function* throttlePerKey(pattern, selector, timeout, saga) {
  const set = new ExpirableSet({ expire: timeout })

  while(true) {
    const action = yield take(pattern)
    const id = selector(action)
    const throttled = set.has(id)
    if (throttled) {
      // Do nothing, action throttled
    } else {
      set.add(id)
      yield call(saga, action)
    }
  }
}

仅使用redux-saga

我们可以使用redux-saga模拟可到期的集合,并获得纯redux-saga解决方案。

代码:

function* throttlePerKey(pattern, selector, timeout, saga) {
  const set = new Set()

  while(true) {
    const action = yield take(pattern)
    const id = selector(action)
    const throttled = set.has(id)
    if (throttled) {
      // Do nothing, action throttled
    } else {
      set.add(id)
      // Expire items after timeout
      yield fork(function* () {
        yield delay(timeout)
        set.delete(id)
      })
      yield call(saga, action)
    }
  }
}