React-控制对服务器的AJAX调用 [英] React - Controlling AJAX calls made to the server
问题描述
在我的React应用程序中,我有一个参数数组(例如,一些ID),应将其用作ajax调用队列的参数.问题在于数组可能包含1000多个项目,如果我仅使用forEach循环递归地进行ajax调用,浏览器页面最终将在每个请求得到解决之前停止响应.
In my React application I have an array of parameters (some IDs, for example), which should be used as a parameters for an ajax call queue. The problem is that array might contain more than 1000 items and if I just recursively make the ajax call using the forEach loop, the browser page eventually stops responding before each of the requests are resolved.
有没有一个库,可以允许发送ajax请求,例如,一次异步维护5个请求.
Is there a library, which could allow to send ajax requests, for example, maintaining 5 requests at a time asynchronously.
这是我现在正在使用的代码.
This is the code which I am using for now.
async function makeBatchCalls(arrayIds, length)
{
//convert arrayIds to two dimensional arrays of given length [[1,2,3,4,5], [6,7,8,9,10] ....]
let test = arrayIds.reduce(
(rows, key, index) => (index % length == 0
? rows.push([key])
: rows[rows.length-1].push(key)) && rows, []);
let Batchresults = [];
for (calls of test) {
Batchresults.push(await Promise.all(calls.map((call)=>fetch(`https://jsonplaceholder.typicode.com/posts/${call}`))));
}
return Promise.all(Batchresults); //wait for all batch calls to finish
}
makeBatchCalls([1,2,3,4,5,6,7,8,9,10,12,12,13,14,15,16,17,18,19,20],5)
此代码的问题是它等待5个呼叫完成,然后发送另一批5个呼叫.这不是对网络的有效利用.我想要的是在任何时间点应该有5个请求.
Problem with this code is it waits for 5 calls to complete and then send another batch of 5 calls. This is not an effective utilisation of the network. What I want is at any point of time there should be 5 requests.
是否可以对上述代码本身进行调整以满足需求?
Is it possible to tweak above code itself to cater the requirements?
推荐答案
这是一个有趣的问题.我可以想到的一种方法是,在第一批中的任何一个完成后立即进行 6th
ajax调用.这样,随时都会有5个ajax请求正在处理中.我试图实现类似的东西.尽管我的解决方案没有进行ajax调用,但是我猜您可以更改 process
函数来进行ajax调用并返回promise.
This is interesting problem to solve. One approach I can think is to make the 6th
ajax call as soon as any one in first batch finishes. This way there will be 5 ajax requests in process at any moment. I have tried to implement something similar. Though my solution does not make ajax calls, but I am guessing you can changed the process
function to make the ajax call and return the promise back.
/**
This function processes the jobs in batches, once a job is finished in batch it then processes the next job. This can be used to make network calls.
*/
function processBatch(queue, batchSize, processJob) {
// remove a batch of items from the queue
const items = queue.splice(0, batchSize);
let count = items.length;
// no more items?
if (!count) {
return Promise.resolve();
}
return new Promise((resolve, reject) => {
return items.forEach((item, i) => {
return processJob(item).then(result => {
return processBatch(queue, 1, processJob)
.then(_ => --count || resolve());
});
});
})
}
// create queue
var queue = [];
for (var i = 1; i <= 20; i++) {
queue.push(i);
}
// a per-item action
function process(item) {
console.log('starting ' + item + '...');
return new Promise((resolve, reject) => {
// (simulating ajax)
return setTimeout(function() {
console.log('completed ' + item + '!');
resolve();
}, Math.random() * 1000);
});
}
// start processing queue!
processBatch(queue, 5, process)
.then(result => console.log("All jobs processed"));
我只是尝试使用Promise实现泛型函数.您可以尝试使用ajax调用来运行相同的代码.我想知道这种解决方案将如何为您服务.
I just tried to implement a generic function using promises. You can try to run same with ajax calls. I would be interested to know how this solution would work for you.
如您所见,在成功执行每个作业后,我递归地调用 processBatch
函数,并且连续的 batchSize
被硬编码为 1
,但是可以更改和参数化.另外,此功能仅在满意的情况下起作用,因为它没有考虑拒绝的承诺.
As you can see, I am recursively calling the processBatch
function after successful execution of each job and the successive batchSize
is hard coded to 1
, but that can be changed and parameterized. Also, this function will work for only happy path case, as it does not take rejected promises into consideration.
这篇关于React-控制对服务器的AJAX调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!