赞
踩
/** * 此问题目的为了解决类似http请求的并发量过大导致内存可能溢出的问题。 */ function concurrentPoll() { this.tasks = []; // 任务队列 this.max = 10; // 最大并发数 // 函数主体执行完后立即执行,由于setTimeout是macrotask(宏任务),promise是microtask(微任务) // 所以,addTask方法添加的函数会优先执行 setTimeout(() => { this.run() }, 0) } concurrentPoll.prototype.addTask = function (task) { // 原型添加任务方法 this.tasks.push(task) } concurrentPoll.prototype.run = function () { // 原型任务运行方法 if (this.tasks.length == 0) { // 判断是否还有任务 return } const min = Math.min(this.tasks.length, this.max); // 取任务个数与最大并发数最小值 for (let i = 0; i < min; i++) { this.max--; // 执行最大并发递减 const task = this.tasks.shift(); // 从数组头部取任务 task().then((res) => { // 重:此时可理解为,当for循环执行完毕后异步请求执行回调,此时max变为0 console.log(res) }).catch((err) => { console.log(err) }).finally(() => { // 重:当所有请求完成并返回结果后,执行finally回调,此回调将按照for循环依次执行,此时max为0. this.max++; // 超过最大并发10以后的任务将按照任务顺序依次执行。此处可理解为递归操作。 this.run(); }) } } const poll = new concurrentPoll(); // 实例 for (let i = 0; i < 13; i++) { // 数据模拟 poll.addTask(function () { return new Promise( function (resolve, reject) { // 一段耗时的异步操作 resolve(i + '成功') // 数据处理完成 // reject('失败') // 数据处理出错 } ) }) }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。