redux saga,有条件地节流/去抖动? [英] redux saga, throttle/debounce conditionally?

查看:84
本文介绍了redux saga,有条件地节流/去抖动?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在记录横幅在屏幕上可见时的展示次数.

I'm logging banner impressions when it is visible on screen.

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

When a user scrolls, the same banner can be made visible multiple times in short time period.

我想防止这种情况发生.

And I'd like to prevent that.

乍一看,throttle 是防止它的完美方法.

On first thought, throttle is perfect way of preventing it.

但是当你在一个页面中有多个横幅时,throttle 不会在屏幕中记录第二个横幅如果被限制.

But then when you have multiple banners in one page, throttle would not log the 2nd banner in screen if throttled.

那么我怎样才能对每个键进行节流?(在本例中,横幅 id 作为键)即,我想根据banner_id 限制横幅展示次数.(这就像服务器限制每个 api 密钥的 api_endpoint 访问)

So how can I throttle per key? (banner id as a key in this example) ie, I want to throttle banner impression per banner_id. (it's like servers throttling api_endpoint access per api keys)

编辑

可以考虑为每个键创建throttle,但不知道它是否会占用太多资源?

One could think of creating throttle for each key, but wonder if it could take up too much resources?

我想知道 Django-rest-framework 等 API 库如何实现每个 api 密钥的节流阀.我想它可能与 saga 油门的作用完全不同.

I wonder how API libraries such as Django-rest-framework implements throttle per api key. I guess it could be totally different from what saga throttle does.

推荐答案

使用过期地图

django-rest 这样的东西使用 expirable map 来限制.一个可过期的 set 也足以完成任务.

Using an expirable map

Things like django-rest use expirable map for throttling. An expirable set is sufficient for the task, too.

不幸的是,我不能为可过期的地图/集合推荐一个精确的 npm 模块.

I cannot recommend an exact npm module for expirable map/set, unfortunately.

伪代码:

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 解决方案.

Using only redux-saga

We can emulate an expirable set with redux-saga, and get a purely redux-saga solution.

代码:

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)
    }
  }
}

这篇关于redux saga,有条件地节流/去抖动?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆