如何解决如何在循环中处理lof Ajax请求并使用JavaScript防止“请求过多”
我正在尝试从Web服务中保存一些信息,这是大量数据,并且我必须发出许多Ajax请求,在如此快速地完成许多请求之后,服务器会抛出“太多请求”,这使得感觉...
我的代码如下:
function getDataFromWS()
{
define some vars
$ make an ajax request to MY database to get every item i will request on the external WS
(that query returns like 150 items to arrayFromresponse)
//Loop into the array with 150 items
arrayFromresponse.forEach((element)=>{
//For loop to make request for each day of the month e.g. August 31 days
for(let i = 1; i <= 31; i++){
//change uri to match each day using i
uriData.date = '2020-08-0'+i;
//This is where after many requests it throws error 429 "Too many"
$.ajax({
data: uriData,url: uri,type: 'GET',async: false,success : function(response){
//Save data from response to some arrays I use
},error: function(response){
console.log(response);
console.log('Error');
}
});
}
})
//After all that looping and requests make a CSV file
buildCSVfile(dataFromresponses);
}
我需要所有这些代码都是同步的,我假设我需要使用诸如setTimeout之类的东西,因为我尝试过,但是buildCSVfile()函数在循环之前执行,我猜延迟应该在每个ajax请求之后在循环日期。也许每个请求10秒,所以它不会说太多请求?所有核心代码都在成功功能中。我并不需要那么快,只是为了确保获得每月每个项目和每个天的所有信息。
我感谢您提供的任何帮助。
解决方法
我建议使用jQuery Deffered,因为您已经在使用jQuery。
阅读jQuery Deferred,以了解内部工作原理。 它基本上实现了一个基于Promises的系统。
您的代码可能最终类似于:
function getDataFromWS()
{
var deferred = new $.Deferred();
var dataFromResponses = [];
// define some vars
// $ make an ajax request to MY database to get every item i will request on the external WS
// (that query returns like 150 items to arrayFromResponse)
var uri = "https://jsonplaceholder.typicode.com/todos/";
var arrayFromResponse = ["SOME DATA"];
//Loop into the array with 150 items
arrayFromResponse.forEach((element)=>{
//For loop to make request for each day of the month e.g. August 31 days
for(let i = 1; i <= 10; i++){
var uriData = {};
//change uri to match each day using i
uriData.date = '2020-08-0'+i;
var def = new $.Deferred();
//This is where after many requests it throws error 429 "Too many"
$.ajax({
data: uriData,cache: false,url: uri + i,type: 'GET',async: false,success : function(response){
console.log("Got data at day " + i);
dataFromResponses.push(response);
},error: function(response){
deferred.reject(response);
console.log('Error');
}
});
}
});
//After all that looping and requests make a CSV file
deferred.resolve(dataFromResponses);
return deferred.promise();
}
// and call it with:
$.when(getDataFromWS()).done(function(dataFromResponses){
console.log(dataFromResponses);
// buildCSVfile(dataFromResponses);
}).fail(function(response){
console.error(response);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
,
我认为这对后端是一个挑战-它的API应该支持通过一个请求执行此任务。 但是,如果您确定需要进行许多单独的请求,则只需使用并发限制(Live demo):
import CPromise from "c-promise2";
import $ from "jquery";
async function getDataFromWS(url,concurrency) {
return CPromise.all(
function* () {
for (let i = 1; i < 32; i++) {
const uriData = { date: "2020-08-0" + i };
yield $.ajax({
data: uriData,url,type: "GET",dataType: "json",async: true
});
}
},{ concurrency }
);
}
const buildCSVfile = async (responses) => {
console.log(`Done: `,responses.map(JSON.stringify));
};
(async () => {
const data = await getDataFromWS(
`https://run.mocky.io/v3/753aa609-65ae-4109-8f83-9cfe365290f0?mocky-delay=1s`,10 // concurrent request limit
);
await buildCSVfile(data);
})();
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。