js如何限制请求并发数?非Promise

167 阅读1分钟

直接上代码:

/**
 * @method 限制请求并发数
 * @param {Object} options -参数
 * @property {Array} options.tasks -promise请求方法队列数组:[this.$api.user.getUserInfo, this.$api.sys.getSystemTime, this.$api.dict.getDicts, ...]
 * @property {Number} options.limit -最大并发数
 * @property {Boolean} options.isAuto -是否自动开始执行 = true 自动立刻执行 | false 则需要手动执行:new LimitConcurrency(options).runQueue() 
 * @property {Function} options.callback -每次执行完的回调
 * @property {Function} options.finallys -全部执行完的回调
 * @example:
	const tasks = [this.$api.user.getUserInfo, this.$api.sys.getSystemTime, this.$api.dict.getDicts, 666]
	const callback = (res, index ,task)=>{console.log(res, index ,task)}
	const finallys = ()=>{console.log("allFinished")}
	let con = new LimitConcurrentcy({tasks, limit: 3, isAuto: true, callback, finallys})
      //实际开发中将tasks元素改为方法就可以,毕竟还要考虑传参
 */
 export class LimitConcurrentcy {
 	constructor(options){
		let defaults = {
			tasks: [],
			limit: 3,
			isAuto: true,
			callback: undefined,
			finallys: undefined
		}
		options = Object.assign({}, defaults, options || {})
		this.tasks = options.tasks.slice()
		this.queue = new Set()
		this.limit = options.limit
		this.index = -1 
		this.count = -1
		this.callback = options.callback
		this.finallys = options.finallys

		options.isAuto && this.runQueue()
	}
	runQueue(){
		if(this.tasks.length === 0 && this.queue.size === 0 && this.count === this.index){
			this.isFunction(this.finallys) && this.finallys()
		}
		while(this.tasks.length > 0 && this.queue.size < this.limit){
			const task = this.tasks.shift()
			this.index++
			this.queue.add(task)
			if(!this.isFunction(task)){
				this.currentFinally(null, this.index, task)
				continue
			}
			this.runTask(task, this.index)
		}
	}
	runTask(task, index){
		//这里也可以直接用finally()回调代替,小编这里是为了兼容旧版本浏览器
		task().then((res)=>{
			this.currentFinally(res, index, task)
		}).catch((err)=>{
			this.currentFinally(err, index, task)
		})
	}
	isFunction(obj){
		return typeof obj === 'function' && Object.prototype.toString.call(obj) === '[object Function]'
	}
	runCallback(res, index ,task){
		this.isFunction(this.callback) && this.callback(res, index, task)
	}
	currentFinally(res, index, task){
		this.queue.delete(task)
		this.runCallback(res, index, task)
		this.count++

		this.runQueue()
	}
	addTask(...task){
		/**
		* @method 实例增加任务队列:con.addTask(...task)
		* @params {Array | Function} ...task -接受多参数:数组或者数组扩展或者单、多个function
		*/
		if(Array.isArray(...task)){
			this.tasks = this.tasks.concat(...task)
		}else{
			this.tasks.push(...task)
		}
		this.runQueue()
	}
 }