简体   繁体   English

有没有办法保持 HTTP 请求直到挂起的请求数小于 N?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM