React - 控制多个Ajax调用 [英] React - Controlling multiple Ajax Calls

查看:66
本文介绍了React - 控制多个Ajax调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的反应应用程序中,我有一个Grid。用户可以一次选择多个网格行,然后单击按钮对选定的网格行进行批量操作。

In my react application, I have a Grid. User can select many grid rows at a time and click on a button to take bulk action on selected grid rows.

在服务器端,我有一个我想要的脚本执行每个选定的行(为了使问题变得简单,我在点击批量操作按钮时,在下面的示例中为每个选定的行调用jsonplaceholder.typicode.com)。在批量操作按钮单击时,我在动作创建器中获得selectedRows,我在其中迭代selectedRows并为每个所选行进行ajax调用。

On a server side I have a script which I want to execute for each selected row (to make question simple I am making call to "jsonplaceholder.typicode.com" in the example below for each selected row) on a click of a bulk action button. On bulk action button click, I get selectedRows in action creator, where I iterate over selectedRows and make ajax call for each of the selected row.

由于selectedRows可能包含超过1000个项目,并且如果我只是使用forEach循环迭代地进行ajax调用,浏览器页面最终可能会在每个请求之前停止响应解决。因此我使用下面的解决方案,以5个批次发送请求,然后等到5个解决。

Since selectedRows may contain more than 1000 items and if I just iteratively make the ajax call using the forEach loop, the browser page may eventually stop responding before each of the requests are resolved. Hence I used solution below, to send request in a batch of 5 and then wait until those 5 are resolved.

// Action creator, selectedRows is an array.
function onGridRowsSelection(selectedRows) {
   makeBatchCalls(selectedRows,5)
}

async function makeBatchCalls(selectedRows, length) {
    let test = arrayIds.reduce((rows, key, index) => (index % length == 0 
                ? rows.push([key]) 
                : rows[rows.length-1].push(key)) && rows, []);
    let Batchresults = []; //convert them to two dimensionl arrays of given length [[1,2,3,4,5], [6,7,8,9,10]]
    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
}

上面的解决方案工作正常,但有一个问题,

Solution above works fine, but has one problem,


  1. 从网格中选择5行以上,然后点击批量操作按钮,

  2. 再次选择超过5行并单击批量操作按钮,

  3. 现在我看到一次有10个请求处于活动状态。

如何限制?

问题的后续问题这里提到的是 React - 在复杂的应用程序中巧妙地控制异步调用而没有任何副作用

Follow up question for the problem mentioned here is asked in React - controlling async calls smartly without any side effect in complex applications

此问题是 JavaScript,React - 同时发送多个ajax呼叫的后续问题

推荐答案

async 模块具有以下功能: async.queue 。首先定义一个任务函数。然后你给它一个任务 - 在你的情况下,一个行数组和你想要它采取的行动。如果正在进行任务,则将运行该任务,或将其添加到队列中。任务完成后,下一个任务将从队列中获取。

The async module has a function for this: async.queue. First you define a task function. Then you give it a task - in your case, an array of rows and the action you want it to take. The task will be run, or added to the queue if there is already a task in progress. When a task is completed, the next one will be taken from the queue.

更好的是,你可以只为一行定义任务函数并设置并发当用户单击该按钮时,会向队列中添加许多任务,每个任务对应一行。 5个任务将立即开始运行,其余任务将排队。这可能比你想做的更好,因为这样用户可以启动2个任务,然后立即启动另外3个任务,并且它们将并行运行。

Better yet, you could define the task function for just one row and set the concurrency of the queue to 5. When the user clicks the button, you add lots of tasks to the queue, one for each row that was selected. 5 tasks will start running immediately, and the rest will be queued. This is probably better than what you're trying to do, because this way the user can start 2 tasks and then immediately start another 3, and they will all run in parallel.

尝试以下代码:

const async = require('async');    // or whatever mechanism you're using for module management.

const queue = async.queue((row, callback) => {
    fetch(`https://jsonplaceholder.typicode.com/posts/${call}`)
        .then(callback, callback);
}, 5);

function onGridRowsSelection(selectedRows) {
    for (let call of selectedRows) {
        queue.push(call);
    }
}

这篇关于React - 控制多个Ajax调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆