前端并发请求控制,一次最多并发3个
screens 监控详情页面,可以添加任意多个图表,当加载页面时,一次可能同时加载100个图表,就至少请求100个接口,此时有些服务可能就会请求不成功而报错。
分析原因:一次请求过多接口时,服务器承受不住就会失败
解决方案:前端控制一次最多请求3个接口,再以此请求后面的接口
concurrent.js - 封装请求拦截
// fake request
const request = (url, callback) =>
setTimeout(() => callback(`request "${url}" si finished`), 2000);
// function promisify
const toPromise = (url, req) => new Promise((resolve) => req(url, resolve));
// multiple requests
const concurrent = (urls, max) => {
// transform the requests to a queue of runners
const queue = urls.map((url) => () => toPromise(url, request));
// slice to two queues
const init = queue.slice(0, max);
const rest = queue.slice(max);
// construct a composer
const executor = (runner, rest) =>
runner().then((result) => {
// handle request result
console.log(result);
// arrange those requests
// the next request is initiated only if one request is completed,
// so it can be judged that only a certain number of requests are in a concurrent state
if (rest.length > 0) {
const runner = rest.shift();
executor(runner, rest);
}
});
init.forEach((runner) => executor(runner, rest));
};
const urls = [
"url 1",
"url 2",
"url 3",
"url 4",
"url 5",
"url 6",
"url 7",
"url 8",
"url 9"
];
concurrent(urls, 2);
页面中需要请求100个图表接口,控制最多并发3个请求
/**
* 控制并发请求
* 需求:页面中需要请求100个图表接口,控制最多并发3个请求
*/
const limitRequest = (max) => {
const limit = max;
const requests = [];
let currentSum = 0;
const run = async() => {
try {
++currentSum;
const fn = requests.shift();
await fn();
} catch (err) {
console.log("Error", err);
} finally {
--currentSum;
if (requests.length > 0) {
run();
}
}
}
return (reqFn) => {
if (!reqFn || !(reqFn instanceof Function)) {
console.error("当前请求不是一个Function", reqFn);
return;
}
requests.push(reqFn);
if (currentSum < limit) {
run();
}
}
}
let a = (msg) => () => new Promise((resolve) => {
setTimeout(() => {
resolve(msg);
}, 1000);
}).then((data) => console.log(data));
let newRequest = limitRequest(3);
newRequest(a(1));
newRequest(a(2));
newRequest(a(3));
newRequest(a(4));
newRequest(a(5));
newRequest(a(6));