现有一个页面要执行十个不同的请求,第一次加载此页面时,从第一个请求开始依次执行,执行完一个请求后延迟10s再执行下一个;
每个请求执行后,每间隔30s会再次重复请求自己;
并且在中途可以添加新请求,或者删除老请求
这个业务场景的效果怎么实现比较好呢?
现有一个页面要执行十个不同的请求,第一次加载此页面时,从第一个请求开始依次执行,执行完一个请求后延迟10s再执行下一个;
每个请求执行后,每间隔30s会再次重复请求自己;
并且在中途可以添加新请求,或者删除老请求
这个业务场景的效果怎么实现比较好呢?
// 请求对象相关存储,子元素最好是个对象,这里用数字简单代替
let ajaxOpts = [1,2,3,4,5,6,7,8,9,10];
function ajax () {
// 发请求处理逻辑
}
// 注册定时请求
function regInterval (urlopt) {
if (!urlopt) {
return;
}
urlopt.interId = setInterval(function () {
ajax(urlopt);
}, 30000);
}
// 逐个发起请求
function shiftAjax (arr, nofirst) {
if (!arr || !arr.length) {
return;
}
setTimeout(function () {
let a = arr.slice(),
urlopt = a.shift();
ajax(urlopt);
regInterval(urlopt);
shiftAjax(a, true);
}, nofirst ? 10000 : 0);
}
shiftAjax(ajaxOpts);
await getData1()
await sleep(10*1000)
await getData2()
await sleep(10*1000)
await getData3()
...
var queue = (() => {
let stack = [];
let stop = false;
function add(fn) {
stack.push(fn);
}
function remove(fn) {
stack = stack.filter(f => f !== fn);
}
function clear() {
stack.length = 0;
}
function fire() {
if(stop) return;
stop = true;
next();
}
function next(...arg) {
const fn = stack.shift();
if(fn) fn.apply(null, arg.concat(next))
}
return {add, remove, clear, fire};
})();
function ajax(option) {
setTimeout(() => {
option.success(option.data)
}, Math.random()*100)
}
function test() {
Array(4).fill().map((_,i) => i).forEach(num => {
const fn = next => {
ajax({
data: num,
success: res => {
console.log(typeof next)
console.log('ajax'+num, res, new Date().toLocaleTimeString())
next && setTimeout(next, 1*1000)
setTimeout(fn, 3*1000)
}
})
};
queue.add(fn)
})
queue.fire()
}
test()
提供一个不一样的思路,用队列。
不具体实现了,倒是做过类似的功能,写个伪代码吧:
// 先写一个函数,用来构建循环请求,我这里对同一个 URL 只请求一次
const pool = {};
function createPeriodicPulling(url, options) {
if (url in pool) {
return pool[url];
}
const pp = new PeriodicPulling(url, options);
pool[url] = pp;
return pp;
}
class PeriodicPulling {
contructor(url, options) {
}
// 启动循环请求
start() {
}
// 重置下一次,等待 `delay` ms
next(delay) {
}
// 停止循环请求
stop() {
}
}
// 在业务代码中使用
const urls = [....]; // 共10个url
function startPeriodicPulling() {
if (urls.length === 0) {
return;
}
const url = urls.shift();
createPeriodicPulling(url, {
duration: 3E4, // 30s
});
setTimeout(startPeriodicPulling, 1E4); // 10s
}
startPeriodicPulling();
10 回答11.7k 阅读
2 回答3.2k 阅读✓ 已解决
2 回答4.3k 阅读✓ 已解决
4 回答4.6k 阅读✓ 已解决
3 回答1.9k 阅读✓ 已解决
4 回答2.1k 阅读✓ 已解决
2 回答1.7k 阅读✓ 已解决