更新:我现在知道油门会掉落多余的功能调用,因此它不是正确的工具。我仍然喜欢一种惯用的方法来处理队列中的所有项目而不会太快或丢弃任何项目。
我正在编写一个节点应用程序,它可以使用速率限制来访问API。我可以比我允许发送它们更快地创建调用。我想要消耗一个电话队列,但不要太快或丢掉任何一个。我做了一个小型的typscript测试来说明我的麻烦:
import * as _ from "lodash";
let start = new Date().getTime();
function doLog(s: string) {
let elapsed = new Date().getTime() - start;
console.log(`${s} ${elapsed}`);
}
let array = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'];
let throttled = _.throttle(doLog, 100);
array.forEach(s => throttled(s));
我希望看到输出大致如下:
a 2
b 101
c 203
d 302
e 405
f 502
g 603
h 706
i 804
j 902
但相反,我看到了:
a 2
j 101
我做了一些奇怪的观察:
答案 0 :(得分:2)
如果在等待期间多次调用受限制的函数,则忽略后续调用。如果您需要处理数组中的每个项目,throttle()
可能不是您想要的。例如,它更适合防止UI中的过度更新。
您在输出中始终看到a
和j
的原因是由于前沿和后沿。整个数组的处理时间不到100毫秒,但由于前导和尾随默认值为true,因此您可以看到这两个调用(对限制函数的第一次和最后一次调用)。
答案 1 :(得分:2)
如果你不关心doLog()
安全"完成"在调用下一个之前,您可以使用setTimeout
let array = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'];
array.forEach((s, i) => setTimeout(doLog, i*100, s));
Adam 给出了一个很好的解释,说明为什么throttle
在这种情况下并不好。
答案 2 :(得分:0)
如果您愿意使用RxJS,这个答案可以让您在习惯上做到这一点: