Редакция саги, газ / дебат условно? - PullRequest
0 голосов
/ 15 октября 2018

Я регистрирую показы баннеров, когда они видны на экране.

Когда пользователь прокручивает, один и тот же баннер можно сделать видимым несколько раз за короткий промежуток времени.

И я бы хотел это предотвратить.

С первого взгляда, throttle - идеальный способ предотвратить это.

Но тогда, когда у вас есть несколько баннеров на одной странице, throttle не будет регистрировать 2-й баннер на экране, если задушено.

Так, как я могу дросселировать на клавишу?(идентификатор баннера в качестве ключа в этом примере), т.е. я хочу ограничить показ баннера для banner_id.(это похоже на то, как серверы регулируют доступ api_endpoint для ключей API)

РЕДАКТИРОВАТЬ

Можно подумать о создании throttle для каждого ключа, но интересно, может ли это занять слишком много времени?много ресурсов?

Интересно, как библиотеки API, такие как Django-rest-framework, реализуют Throttle для API-ключа.Я думаю, это может полностью отличаться от того, что делает газ саги.

1 Ответ

0 голосов
/ 16 октября 2018

Использование расширяемой карты

Такие вещи, как django-rest, используют расширяемая карта для регулирования.Для этой задачи достаточно и расширяемого набора set .

К сожалению, я не могу рекомендовать точный модуль npm для расширяемой карты / набора.

Псевдокод 1013 *:

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