Open Twlig opened 2 years ago
let request1 = () => new Promise((resolve, reject) => { setTimeout(() => { resolve(1); }, 2000); }); let request2 = () => new Promise((resolve, reject) => { setTimeout(() => { resolve(2); }, 1200); }); let request3 = () => new Promise((resolve, reject) => { setTimeout(() => { resolve(3); }, 100); }); let request4 = () => new Promise((resolve, reject) => { setTimeout(() => { resolve(4); }, 100); });
let addRequest = scheduler(2); addRequest(request1).then((res) => { console.log(res); }); addRequest(request2).then((res) => { console.log(res); }); addRequest(request3).then((res) => { console.log(res); }); addRequest(request4).then((res) => { console.log(res); }); //输出 2,3,4,1
精髓在于:
scheduler返回一个new Promise,通过resolve,reject来释放异步请求的结果。
tasks队列记录异步任务,以及resolve,reject函数,便于在得到异步结果的时候直接resolve或者reject。
使用tasks和pengdingCount以闭包的形式,在每次触发addRequest的时候把异步请求添加到任务队列。
run函数的编写,每次调用addRequest,加入任务队列后就执行run。
run函数内部,要经过任务队列长度,pendingCount的大小决定是否可以执行异步请求。
每次执行任务是以shift的形式从任务队列中取出事件。
function scheduler(max = 10) { let tasks = [], pendingCount = 0; function run() { if (tasks.length > 0 && pendingCount < max) { pendingCount++; const { task, resolve, reject } = tasks.shift(); task() .then( (res) => { resolve(res); }, (err) => { reject(err); } ) .finally(() => { pendingCount--; run(); }); } } return function (task) { return new Promise((resolve, reject) => { tasks.push({ task, resolve, reject }); run(); }); }; }
处理并发请求,以下是模拟异步请求,需要编写并发请求控制函数scheduler:
函数的用法如下:
scheduler函数实现:
精髓在于:
scheduler返回一个new Promise,通过resolve,reject来释放异步请求的结果。
tasks队列记录异步任务,以及resolve,reject函数,便于在得到异步结果的时候直接resolve或者reject。
使用tasks和pengdingCount以闭包的形式,在每次触发addRequest的时候把异步请求添加到任务队列。
run函数的编写,每次调用addRequest,加入任务队列后就执行run。
run函数内部,要经过任务队列长度,pendingCount的大小决定是否可以执行异步请求。
每次执行任务是以shift的形式从任务队列中取出事件。