考点: 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());}}}
