簡體   English   中英

處理 NodeJS 中的速率限制 API

[英]Dealing with rate limiting APIs in NodeJS

所以我需要一種方法在給定的秒內運行函數 x 次,然后等到下一秒運行下一組。 我正在使用 Yelp Fusion API 調用“搜索” https://api.yelp.com/v3/search ,然后對每個搜索結果運行詳細信息查詢: https ://api.yelp.com/ v3/businesses/business_id

因此,第一個搜索查詢會返回一系列企業,如下所示:

const businesses = response.body.businesses
for (business of businesses) {
    fetchPlaceDetails(business.id)
}

從理論上講,我可以以異步方式運行 fetchPlaceDetails(),但是通過 50 多個結果需要太長時間。 相反,我想運行查詢可能 5 次,等待一秒鍾(超過速率限制),運行接下來的 5 次,等待一秒鍾,運行接下來的 5 次,等等。

不知道如何實現這一點,但我認為在使用具有速率限制的 API 時,這一定是一個非常標准的問題。 另外,我不確定但在文檔中沒有看到指定的實際呼叫/秒限制,但我假設它可能是 10 個請求/秒左右?

我想運行查詢可能 5 次,等待一秒鍾(超過速率限制),運行下一個 5,等待一秒鍾,運行下一個 5,等等。

然后這樣做:

const {businesses} = response.body;
for (let i=0; i<businesses.length; i+=5) {
    await Promise.all([
        ...businesses.slice(i, i+5).map(({id}) => fetchPlaceDetails(id)),
        new Promise(resolve => { setTimeout(resolve, 1000); })
    ]);
}

如果 5 個請求花費的時間比這更長,這也將確保您在批次之間等待超過一秒。

這是一個“通用”方法,用於檢查存儲數組是否包含任何數據,如果包含,它會處理數組中的nn個項目,然后等待ii秒數並重復該過程。

 const queue = (() => { let itemsPerStep = 5, //number of items process per step intervalSpeed = 5000, //how long to wait between steps in miliseconds stopWhenDone = true, //when queue list depleted stop the loop prevDate = 0, timer; const list = []; //queue list const commands = { add: item => list.unshift(item), get list() { return list; }, clear: () => list.length = 0, speed: (val = intervalSpeed) => intervalSpeed = val, itemsPerStep: (val = itemNumberPerStep) => itemNumberPerStep = val, stop: () => (timer && console.log("stopped"), timer = clearInterval(timer)), start: (t = true) => (stopWhenDone = t, commands.stop(), timer = setInterval(loop), loop()) }; const loop = () => { const now = new Date(); if (now - prevDate < intervalSpeed) return; if (!list.length) { if (stopWhenDone) commands.stop(); return; } prevDate = now; let res = []; //example result storage for(let i = 0; i < itemsPerStep && list.length; i++) { const value = list.pop(); //get item from the queue list res.push(value); //process value } console.log("processed ids: " + res); } //loop() return commands; })(); //generate ids for(let i = 100; i < 230; i += 11) queue.add(i); queue.start();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM