考点: promise的应用能力
Promise 异步流程控制
预备
promise中race、all、allSettled 区别
- Promise.race(iterable) 某个解决/拒绝
- Promise.all(iterable) 有一个被拒绝就抛出异常, 否则全部结束后以数组形式返回
- Promise.allSettled(iterable) 全部结束后, 以数组形式返回结果
- Promise.any(iterable) 有一个成功及返回成功, 全部失败抛出异常 (暂未被浏览器完全支持)
请求池[快手]
实现可控制并发请求数的请求方法
实现可控制并发请求数的请求方法,并且最大化利用空闲通道
// 实现可控制并发请求数的请求方法,并且最大化利用空闲通道
// 提供fetch函数做网络请求,可以这样调用
实现一个批量请求函数 multiRequest(urls, maxNum),要求如下:
• 要求最大并发数 maxNum
• 每当有一个请求返回,就留下一个空位,可以增加新的请求
• 所有请求完成后,结果按照 urls 里面的顺序依次打出复制代码
参考答案:
function multiRequest(urls = [], maxNum) { // 请求总数量
const len = urls.length; // 根据请求数量创建一个数组来保存请求的结果
const result = new Array(len).fill(false); // 当前完成的数量
let count = 0;
return new Promise((resolve, reject) => {// 请求maxNum个
while (count < maxNum) {
next();
}
function next() {
let current = count++; // 处理边界条件
if (current >= len) {
// 请求全部完成就将promise置为成功状态, 然后将result作为promise值返回
!result.includes(false) && resolve(result);
return;
}
const url = urls[current];
console.log(`开始 ${current}`, new Date().toLocaleString());
fetch(url)
.then((res) => {
// 保存请求结果
result[current] = res;
console.log(`完成 ${current}`, new Date().toLocaleString());
// 请求没有全部完成, 就递归 if (current < len) {
next();
}
})
.catch((err) => {
console.log(`结束 ${current}`, new Date().toLocaleString());
result[current] = err;
// 请求没有全部完成, 就递归
if (current < len) {
next();
}
});
}
});
}
相似描述:
实现一个n个请求并发的sendRequest(urls, max, callback)函数
请实现下的函数,可以批量请求数据,所有的url地址在urls参数中,同时可以
通过max参数控制请求的并发度,当所有请求结束之后,需要执行callback回调函数,
发请求的函数可以直接使用fetch即可
异步调度器schedule[字节]
js实现一个带并发限制的异步调度器schedule,保证同时运行的任务最多有两个。
完善下边代码中的Scheduler 类, 是的以下程序正确输出。
class Scheduler {
add(promiseCreator) {
// TODO
}
}
const timeout = (time) => new Promise(resolve => {
setTimeout(resolve, time)
})
const scheduler = new Scheduler()
const addTask = (time, order) => {
scheduler.add(() => timeout(time)).then(() => console.log(order))
}
addTask(1000, '1');
addTask(500, '2');
addTask(300, '3');
addTask(400, '4');
// output: 2 3 1 4
// 一开始, 1, 2两个任务进入队列
// 500ms时, 2完成, 输出2, 任务3进队
// 800ms时, 3完成, 输出3, 任务4进队
// 1000ms时, 1完成, 输出1
Promise.race
class Scheduler {
constructor (maxCount) {
this.maxCount = maxCount || 2;
this.taskList = [];
this.process = [];
}
add(promiseCreator) {
this.taskList.unshift(promiseCreator)
return this.start();
}
start () {
if (this.process.length < this.maxCount && this.taskList.length > 0) {
let task = this.taskList.pop();
let promise = task().then(() => {
let index = this.process.indexOf(promise);
this.process.splice(index, 1);
});
this.process.push(promise);
return promise;
} else {
return Promise.race(this.process).then(() => this.start());
}
}
}