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

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

问题描述

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

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 - 在复杂应用程序中巧妙地控制异步调用而没有任何副作用

这个问题是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.当用户单击按钮时,您将向队列中添加大量任务,每行一个任务.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天全站免登陆