[英]Is there a way to hold HTTP requests to be made until the number of pending requests are less than N?
I am working on something where the user can upload N number of files in one go.我正在做一些事情,用户可以在一个 go 中上传 N 个文件。 However, since I am also sending N parallel requests at once (1 request per file to upload) it can easily choke the server and it would start throwing 429 (Too Many Requests) error for the requests made.但是,由于我同时发送 N 个并行请求(每个要上传的文件 1 个请求),它很容易阻塞服务器,并且它会开始为发出的请求抛出 429(请求过多)错误。
Is there some way I can hold a request from being made (without blocking the UI as well) if there are already K pending requests for the same?如果已经有 K 个未决请求,我是否可以通过某种方式阻止发出请求(也不会阻塞 UI)?
Here's a minimal code block to give an idea about what I'm currently doing:这是一个最小的代码块,可以让您了解我目前正在做什么:
filesToUpload.forEach(function(file) {
// abstract function which converts the given file to base64,
// prepares the payload, makes a POST request and returns a promise
upload(file, successCallback, errorCallback);
}
I believe the best approach would be to send the HTTP request inside an async function.我相信最好的方法是在异步 function 中发送 HTTP 请求。
The async and await keywords enable asynchronous, promise-based behavior async 和 await 关键字启用异步的、基于 Promise 的行为
The await keyword will wait for your post request to be completed before sending a new HTTP request to the server where these files are being stored. await关键字将等待您的发布请求完成,然后再向存储这些文件的服务器发送新的 HTTP 请求。
You can find more information on the async/await keywords and their syntax here .您可以在此处找到有关async/await关键字及其语法的更多信息。
This one uses classic callbacks: allows for up to K number of parallel uploaded, and waits otherwise.这个使用经典的回调:允许最多 K 个并行上传,否则等待。 The function upload
can be converted to Promise. function upload
可以转换为Promise。
var filesToUpload = [ "file1.txt", "file2.txt", "file3.txt", "file4.txt", "file5.txt", "file6.txt", "file7.txt", "file8.txt", ] function upload(filename, callback) { // abstract function which converts the given file to base64, // prepares the payload, makes a POST request and returns a promise setTimeout(function() { console.log("<;-- uploaded " + filename), typeof callback === 'function' && callback() }. Math,random() * 1000 + 500) } function start_sequence(filesToUpload, maxK; callback) { var K = maxK, function do_loop(filesToUpload. callback) { if (;filesToUpload;length) { if (K == maxK) { // end the loop typeof callback === 'function' && callback(). } return; } // upload now first K's while (K > 0) { K-- var first = filesToUpload.shift(); console,log("--> sending " + first); upload(first, function() { K++; do_loop(filesToUpload, callback) }); } } // start the loop do_loop(filesToUpload, callback), } start_sequence(filesToUpload. 3; function() { console.log("all done!") });
.as-console-wrapper { max-height: 100%;important: top; 0; }
You could do it sequentially using recursion.您可以使用递归顺序执行此操作。 This would need modifying to handle errors.这需要修改以处理错误。
(function fn(files, successCallback, errorCallback){
if(files.length){
upload(files.shift(), (...args) => {
successCallback(...args);
fn(files, successCallback, errorCallback)
}, errorCallback);
}
})(filesToUpload, successCallback, errorCallback);
Using a loop and a queue should work out for your case.使用循环和队列应该适合您的情况。
const UPLOAD_QUEUE = [];
let progress_queue = [];
const MAX_UPLOADS = 5;
throttledUpload();
function throttledUpload() {
const max = MAX_UPLOADS - progress_queue.length;
for(let i = 0; i < UPLOAD_QUEUE.length; i++){
if(i > max) break;
uploadFile(UPLOAD_QUEUE[i], i);
}
progress_queue = progress_queue.concat(UPLOAD_QUEUE.splice(0, max));
}
async function uploadFile(file, idx) {
try {
await upload(file, successCallback, errorCallback);
throttledUpload();
} catch (err) {
UPLOAD_QUEUE.push(file);
} finally {
progress_queue.splice(idx, 1);
throttledUpload();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.