我有一个返回promise的方法,并且在内部该方法调用一个API,该API每分钟只能有20个请求。问题是我有很多对象(大约300个),并且我想为每个对象调用API。
目前,我有以下代码:
const bigArray = [.....]; Promise.all(bigArray.map(apiFetch)).then((data) => { ... });
但是它不处理时序约束。我希望我可以使用_.chunk和_.debounce之类的东西,lodash但是我无法解决这个问题。有人可以帮我吗?
lodash
您可以每分钟发送1个包含20个请求的块,或者每3秒将其间隔1个请求(这可能是API所有者更喜欢的)。
function rateLimitedRequests(array, chunkSize) { var delay = 3000 * chunkSize; var remaining = array.length; var promises = []; var addPromises = function(newPromises) { Array.prototype.push.apply(promises, newPromises); if (remaining -= newPromises.length == 0) { Promise.all(promises).then((data) => { ... // do your thing }); } }; (function request() { addPromises(array.splice(0, chunkSize).map(apiFetch)); if (array.length) { setTimeout(request, delay); } })(); }
要每3秒拨打1个电话:
rateLimitedRequests(bigArray, 1);
或每分钟20个:
rateLimitedRequests(bigArray, 20);
如果您喜欢使用_.chunk和1: _.debounce _.throttle
_.chunk
_.debounce
_.throttle
function rateLimitedRequests(array, chunkSize) { var delay = 3000 * chunkSize; var remaining = array.length; var promises = []; var addPromises = function(newPromises) { Array.prototype.push.apply(promises, newPromises); if (remaining -= newPromises.length == 0) { Promise.all(promises).then((data) => { ... // do your thing }); } }; var chunks = _.chunk(array, chunkSize); var throttledFn = _.throttle(function() { addPromises(chunks.pop().map(apiFetch)); }, delay, {leading: true}); for (var i = 0; i < chunks.length; i++) { throttledFn(); } }
1您可能想要,_.throttle因为它会在延迟后执行每个函数调用,而_.debounce将多个调用组合为一个调用。请参阅本文链接的文档
防抖动 :将其视为“将多个事件组合在一起”。想象您回家,进入电梯,门正在关闭…突然间,您的邻居出现在大厅里,试图跳上电梯。讲礼貌!并为他打开门:您正在取消电梯的离开。考虑到第三人可能再次发生相同的情况,依此类推……可能会将出发时间延迟了几分钟。 油门 :将其视为阀门,它调节执行流程。我们可以确定某个函数在特定时间内可以被调用的最大次数。因此,在电梯类比中,您很有礼貌地允许人们进入10秒钟,但是一旦延迟过去,您就必须走!
防抖动 :将其视为“将多个事件组合在一起”。想象您回家,进入电梯,门正在关闭…突然间,您的邻居出现在大厅里,试图跳上电梯。讲礼貌!并为他打开门:您正在取消电梯的离开。考虑到第三人可能再次发生相同的情况,依此类推……可能会将出发时间延迟了几分钟。
油门 :将其视为阀门,它调节执行流程。我们可以确定某个函数在特定时间内可以被调用的最大次数。因此,在电梯类比中,您很有礼貌地允许人们进入10秒钟,但是一旦延迟过去,您就必须走!