设计一个函数,该函数的参数为可同时发送请求的大小,返回一个函数,该函数的参数为要请求的url。 实现的效果为,同时发送n个请求,当有请求返回后往请求队列里push新的请求,并输出刚刚结束的请求的返回值。
Sunny-117 opened this issue · comments
设计一个函数,该函数的参数为可同时发送请求的大小,返回一个函数,该函数的参数为要请求的url。 实现的效果为,同时发送n个请求,当有请求返回后往请求队列里push新的请求,并输出刚刚结束的请求的返回值。
function scheduler(tasks, max) {
// 当前并发数
let count = 0;
// 阻塞队列
let queue = [];
async function add(task) {
if (count >= max) {
// 阻塞
await new Promise((resolve) => queue.push(resolve));
}
count++;
task().then((data) => {
count--;
// 阻塞队列有无阻塞
if (queue.length) queue.shift()();
});
}
for (let i = 0; i < tasks.length; i++) {
add(tasks[i]);
}
}
思路仅供参考,每个request方法都支持promise回调,使用递归+队列,只考虑了成功态了
function scheduler(max) {
const queue = []
let run = 0
return function(url) {
queue.push(function() {
// return fetch(url)
return new Promise(res => {
setTimeout(()=> {
res(url)
}, url)
})
})
return new Promise(resolve => {
execute()
function execute() {
if (run < max && queue.length) {
const task = queue.shift()
run++
task().then((value)=> {
resolve(value)
console.log(value)
}).finally(()=> {
run--
execute()
})
}
}
})
}
}
const addToRequest = scheduler(2)
addToRequest(1000)
addToRequest(500)
addToRequest(400)
addToRequest(300)
addToRequest(100)
function scheduler(max) {
const queue = []
let count = 0
function getCall() {
if (queue[0]) {
const obj = queue.shift()
step(obj.url, obj.cb)
}
}
function step(url, cb) {
if (count < max) {
count++
if (cb) {
setTimeout(() => {
count--
cb(url)
getCall()
}, url);
} else {
return new Promise(resolve => {
setTimeout(() => {
count--
resolve(url)
getCall()
}, url);
})
}
} else {
return new Promise(resolve => {
queue.push({
url,
cb: resolve
})
})
}
}
return step
}
const request = scheduler(2)
request(1000).then(res => console.log(res))
request(2000).then(res => console.log(res))
request(3000).then(res => console.log(res))
request(1000).then(res => console.log(res))
request(4000).then(res => console.log(res))
// 1000 2000 1000 3000 4000