时间窗口
在一定时间内,如果请求同一个 url,则只请求一次。
const fetch = require("node-fetch");
function hash(...args) {
return args.join(",");
}
function window_request(f, time = 50) {
let w = {};
// 是否有时间窗口
let flag = false;
return (...args) => {
return new Promise((resolve) => {
// 如果w中没有这次请求(通过hash存入), 如果有,则在最后 L54 将resolve存入到对应的resolvers里
if (!w[hash(args)]) {
w[hash(args)] = {
func: f,
args,
// 将不同的request的resolve也添加进来,方便最后统一做处理。
resolvers: [],
};
}
// 如果没有时间窗口
if (!flag) {
// 接下来是创建一个时间窗口
console.log("create a window");
flag = true;
setTimeout(() => {
// 对w中每一个请求进行处理。
Object.keys(w).forEach((key) => {
// 获取参数进行执行
const { func, args, resolvers } = w[key];
console.log("run once ---- ", resolvers.length);
func(...args)
.then((res) => {
return res.text();
})
.then((t) => {
// 将获取到的结果批量放到resolve中处理
resolvers.forEach((r) => {
console.log("result anywhere");
r(t);
});
// 重置访问窗口
flag = false;
w = {};
});
});
}, time);
}
w[hash(args)].resolvers.push(resolve);
});
};
}
const request = window_request(fetch, 20);
request("https://www.baidu.com");
request("https://www.baidu.com");
request("https://www.baidu.com");
request("https://www.baidu.com");
request("https://www.baidu.com");
request("https://www.baidu.com");
request("https://www.baidu.com");
console.log("break");
setTimeout(() => {
request("https://www.baidu.com");
request("https://www.baidu.com");
request("https://www.baidu.com");
request("https://www.baidu.com");
request("https://www.baidu.com");
request("https://www.baidu.com");
request("https://www.baidu.com");
}, 10000);