繁体   English   中英

即使在 window 之后,如何使用油门限制通话?

[英]How can I limit the call with throttle even after the window?

我想在 3 秒内限制 function 的调用不超过一次。 但希望它可以首先被调用并在等待后延迟所有其他人。 我的用例是,限制发送请求,然后在等待第三方服务时批量处理。 但不是第一个电话,等待第一个电话很痛苦。

所以我像这样用lodash做了一个油门

const maxThrottle = _.throttle(() => console.log(new Date()), 3000, { trailing: true, leading: true })

电话是:

console.log('start: ', new Date())
maxThrottle()
await setTimeout(100)
maxThrottle()
await setTimeout(3000)
maxThrottle()

我的预期:

start:  2022-09-04T06:58:01.099Z
2022-09-04T06:58:01.100Z
2022-09-04T06:58:04.104Z
2022-09-04T06:58:07.104Z

实际的:

start:  2022-09-04T06:58:01.099Z
2022-09-04T06:58:01.100Z
2022-09-04T06:58:04.104Z
2022-09-04T06:58:04.214Z  // it is violating the speed of service which I want to avoid.

我怎么能用油门呢? 可能吗?

我可以使用以下代码实现该行为:

function limitSpeed(fn: () => void, wait: number) {
  let calledAt: number | null
  let promise: Promise<void> | null
  return () => {
    const timeLeft = calledAt ? wait - (Date.now() - calledAt) : 0
    if (promise)
      return

    if (timeLeft <= 0) {
      calledAt = Date.now()
      fn()
    } else {
      promise = setTimeout(timeLeft).then(() => {
        calledAt = Date.now()
        fn()
        promise = null
      })
    }
  }
}

const maxThrottle = limitSpeed(() => console.log(new Date()), 3000)
console.log('start: ', new Date())
maxThrottle()
await setTimeout(100)
maxThrottle()
await setTimeout(3000)
maxThrottle()

while(true) {
  maxThrottle()
  await setImmediate()
}

结果:

start:  2022-09-04T07:22:13.621Z
2022-09-04T07:22:13.622Z
2022-09-04T07:22:16.630Z
2022-09-04T07:22:19.629Z
2022-09-04T07:22:22.628Z
2022-09-04T07:22:25.627Z
2022-09-04T07:22:28.626Z
2022-09-04T07:22:31.625Z
2022-09-04T07:22:34.624Z
2022-09-04T07:22:37.623Z
2022-09-04T07:22:40.622Z
2022-09-04T07:22:43.621Z
2022-09-04T07:22:46.621Z
2022-09-04T07:22:49.620Z
2022-09-04T07:22:52.619Z
2022-09-04T07:22:55.618Z
2022-09-04T07:22:58.617Z
2022-09-04T07:23:01.616Z
2022-09-04T07:23:04.615Z
2022-09-04T07:23:07.614Z
2022-09-04T07:23:10.613Z
2022-09-04T07:23:13.613Z
2022-09-04T07:23:16.613Z
2022-09-04T07:23:19.613Z
2022-09-04T07:23:22.613Z
2022-09-04T07:23:25.613Z
2022-09-04T07:23:28.613Z
2022-09-04T07:23:31.613Z
2022-09-04T07:23:34.613Z
2022-09-04T07:23:37.613Z
2022-09-04T07:23:40.613Z

看来这是lodash的错误。 它与underscore完美配合。 替换underscore后,问题消失了。 我猜lodash不处理尾随后油门的情况。 它将立即触发,无需等待leading=true

截至 2022 年 9 月, lodash不再维护两年。 所以如果你有同样的问题,我更喜欢切换到underscore

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM