简体   繁体   English

限制对外部 api 节点的调用

[英]Limit calls to external api node

I'm, in node and I have an array of obj {suggestion: 'text', rank: '2'} that I want to use to make a call to bing to get the first result on each of them.我在节点中,我有一个 obj {suggestion: 'text', rank: '2'}数组,我想用它来调用 bing 以获得每个结果的第一个结果。

At the moment, I have managed it using a Promise.all目前,我使用Promise.all管理它

 await Promise.all(suggestions.map(async (s, i) => await bingWebSearch(s.suggestion.replace(/\s/g, '+'), i))).then(r => { suggestions.map((s, i) => console.log(` n${i+1}. ${s.suggestion} | times suggested: ${s.rank} | url: ${s.webpage} `)) }).catch(e => e.message)

that will call the function bingWebSearch and assign the website URL to the obj这将调用 function bingWebSearch 并将网站 URL 分配给 obj

 const bingWebSearch = async (query, i) => { return await axios.get('https://api.bing.microsoft.com/v7.0/search?', { headers: { 'Ocp-Apim-Subscription-Key': SUBSCRIPTION_KEY }, params: { count: 1, mkt: 'en-US', q: query } }).then(r => { if (r.data.webPages) return suggestions[i].webpage = r.data.webPages.value[0].url }).catch(e => console.log(e.message)) }

So basically, this will fire 30 calls to bing, but I am allowed only to do 3/second how I can I achieve it?所以基本上,这将触发 30 次对 bing 的调用,但我只能做 3/秒我怎样才能实现它? I have tried with a setTimeOut, but using the async func is a bit tricky, so it did not work.我尝试过使用 setTimeOut,但使用异步函数有点棘手,所以它不起作用。

here is my suggestion:这是我的建议:

 function delay(ms) { return new Promise(function (resolve) { setTimeout(resolve, ms); }); } const bingWebSearch = (query, ms) => { return new Promise((resolve, reject) => { delay(ms).then(() => { axios.get("https://api.bing.microsoft.com/v7.0/search?", { headers: { "Ocp-Apim-Subscription-Key": SUBSCRIPTION_KEY }, params: { count: 1, mkt: "en-US", q: query } }).then(r => { resolve(r.data.webPages.value[0].url); }).catch(e => { console.log(e.message); // this will just return an empty string as a result, if something goes wrong resolve(""); // you can also reject and handle the exception inside calling for loop // if more advanced error handling is required // reject(e); }); }); }); }; async function load() { const requests = suggestions.map((s, i) => { // delay each request by 400ms to avoid hitting the limit of 3 requests per second const ms = i * 400; return bingWebSearch(s.suggestion.replace(/\s/g, "+"), ms); }); const res = await Promise.all(requests); suggestions.forEach((s, i) => { s.webpage = res[i]; console.log(`n${i + 1}. ${s.suggestion} | times suggested: ${s.rank} | url: ${s.webpage}`); }); } (function () { load(); })();

I refactored bingWebSearch a bit, to only return the result, and not directly changing the list of suggestions.我稍微重构了bingWebSearch ,只返回结果,而不是直接更改建议列表。 Try keeping functions as self contained as possible without external dependencies.尝试在没有外部依赖的情况下尽可能保持函数自包含。

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

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