提问人:Neeraj Kumar 提问时间:8/8/2022 更新时间:8/11/2022 访问量:102
有没有办法将HTTP请求保留到待处理请求数小于N?
Is there a way to hold HTTP requests to be made until the number of pending requests are less than N?
问:
我正在研究用户可以一次上传 N 个文件的东西。但是,由于我还一次发送 N 个并行请求(每个文件上传 1 个请求),它很容易阻塞服务器,并且它会开始为发出的请求抛出 429(请求过多)错误。
如果已经有 K 个待处理的请求,有没有办法阻止发出请求(也不会阻止 UI)?
这里有一个最小的代码块,可以让你了解我目前正在做什么:
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);
}
答:
1赞
Oliveris
8/8/2022
#1
我认为最好的方法是在异步函数中发送HTTP请求。
async 和 await 关键字支持基于 promise 的异步行为
该关键字将等待您的发布请求完成,然后再向存储这些文件的服务器发送新的 HTTP 请求。await
您可以在此处找到有关 和 关键字及其语法的更多信息。async
await
评论
0赞
Jaromanda X
8/8/2022
这很好,只要你返回一个......没有理由认为问题中涉及任何承诺 - “上传”函数可以是任何东西,而且它绝对不会返回 Promise - 此外,如果您展示代码示例,这将是一个更好的答案await
Promise
0赞
Neeraj Kumar
8/8/2022
不,这将使上传按顺序进行,我不想要这样
0赞
IT goldman
8/8/2022
#2
这个使用经典回调:允许最多 K 个并行上传,否则等待。该函数可以转换为 Promise。upload
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;
}
0赞
Jrdo
8/8/2022
#3
您可以使用递归按顺序执行此操作。这需要修改以处理错误。
(function fn(files, successCallback, errorCallback){
if(files.length){
upload(files.shift(), (...args) => {
successCallback(...args);
fn(files, successCallback, errorCallback)
}, errorCallback);
}
})(filesToUpload, successCallback, errorCallback);
评论
0赞
Neeraj Kumar
8/8/2022
不,这将使上传按顺序进行,我不想要这样
0赞
Benz Stevox
8/8/2022
#4
使用循环和队列应该适合您的情况。
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();
}
}
评论
formData