Можно ли регулировать функцию, не прерывая вызовы функций в JS? - PullRequest
0 голосов
/ 29 января 2020

Мне нужна функция, чтобы между определенным вызовом функции было определенное время, очень похожее на то, что делал бы дроссель, но мне нужно, чтобы присутствовали все вызовы функций.

Позвольте мне объяснить:

Давайте представим, что у нас есть функция 10 секунд для функции foo и событие, которое вызывает foobar. Событие запускается 3 раза, по одному каждые 5 секунд. Только первый и последний будут присутствовать, а посередине будет игнорироваться.

Нормальный газ:

[event]--5s--[event]--5s--[event]
[foo]---------10s---------[foo]

Что я нужно, чтобы событие всегда прослушивалось, но через 10 секунд после предыдущего.

[event]--5s--[event]--5s--[event]
[foo]----------10s--------[foo]---------10s--------[foo]

Есть идеи? Я думал о дроссельной заслонке, а также о дебошире, но ни один из них не подошел бы к тому, что мне нужно сделать.

Ответы [ 2 ]

1 голос
/ 29 января 2020

Это довольно просто сделать. Просто создайте массив функциональных объектов и каждые 10 секунд извлекайте самый старый из них и выполняйте его.

    const queue = []
    
    function rateLimit(fn) {
      queue.push(fn)
    }
    
    setInterval(() => {
      const nextFn = queue.shift() // remove the first function, and return it.
      if (nextFn) nextFn() // execute the first function if it exists.
    }, 1000) // Your interval in milliseconds. Set to 1s for testing.
    
    
    rateLimit(() => console.log('A'))
    rateLimit(() => console.log('B'))
    rateLimit(() => console.log('C'))

Вы можете добавить некоторые логи c, чтобы очистить интервал, когда очередь пуста, и запустить его снова до sh, когда появится новый элемент, так что Первый звонок всегда происходит немедленно, если он не ждет. Но я оставляю это упражнение для вас.

0 голосов
/ 30 января 2020

В случае, если кому-то интересно, я использовал ответ Alex Wayne и добавил немного логики c, чтобы лучше контролировать интервал, как он упоминал.

const queue = []
var intervalExecution

function rateLimit(fn) {
  queue.push(fn)
  if (queue.length && !intervalExecution) {
    intervalExecution = setInterval(() => {
      const nextFn = queue.shift()
      if (nextFn) {
        nextFn()
      } else {
        clearInterval(intervalExecution)
        intervalExecution = undefined
      }
    }, 1000)
  }
}

rateLimit(() => console.log('test'))
rateLimit(() => console.log('test'))
rateLimit(() => console.log('test'))
rateLimit(() => console.log('test'))
...