/**
* 队列任务处理模块,可以用来处理依次执行的操作
* @module $ui/utils/queue
* @author 陈华春
*/
import Events from './events'
const taskFunc = function (data) {
return Promise.resolve(data)
}
/**
* 队列任务处理类 继承 [Events]{@link module:utils/events~Events}
* @extends Events
*
* @example
*
* let queue = new Queue(data => {
* return new Promise((resolve, reject) => {
* setTimeout(() => {
* resolve('ok')
* }, 1000)
* })
* }).start()
* queue.push(1)
* queue.push(2)
*/
class Queue extends Events {
/**
* 构造函数
* @param {Function} task 任务处理函数,必须返回Promise实例
* @param {Array} list 初始队列数据
*/
constructor(task, list = []) {
super()
/**
* 任务列表,任务处理的参数列表
* @type {Array}
* @private
*/
this.__list__ = list
/**
* 当前实例是否在等待任务执行结果
* @type {boolean}
*/
this.waiting = false
/**
* 当前实例是否有任务在执行
* @type {boolean}
*/
this.running = false
/**
* 任务处理函数,函数返回值必须是Promise实例
* @type {Function}
*/
this.task = task || taskFunc
}
/**
* 在队列中加入需要处理的任务数据,如果
* @param {*} data 任务数据
* @returns {Queue}
*/
push(data) {
if (Array.isArray(data)) {
this.__list__ = this.__list__.concat(data)
} else {
this.__list__.push(data)
}
this.run()
return this
}
/**
* 执行队列处理
*/
run() {
if (!this.running || this.waiting || this.__list__.length === 0) return
this.waiting = true
const data = this.__list__.shift()
this.task(data).then(res => {
this.waiting = false
/**
* 当前任务执行成功时触发
* @event module:utils/queue~Queue#success
* @param {*} res 任务函数resolve内容
* @param {*} data 当前任务的参数数据
*/
this.$emit('success', res, data)
if (this.__list__.length > 0) {
this.run()
} else {
/**
* 当前队列任务执行完成时触发
* @event module:utils/queue~Queue#complete
*/
this.$emit('complete', this)
}
}).catch(e => {
this.waiting = false
/**
* 当前任务执行失败时触发
* @event module:utils/queue~Queue#error
* @param {*} e 任务函数reject内容
* @param {*} data 当前任务的参数数据
*/
this.$emit('error', e, data, this)
})
return this
}
/**
* 清空队列任务
*/
clear() {
this.__list__ = []
this.waiting = false
return this
}
/**
* 开始运行队列处理任务
* @returns {Queue}
*/
start() {
this.running = true
this.run()
return this
}
/**
* 停止队列处理任务
* @returns {Queue}
*/
stop() {
this.running = false
return this
}
/**
* 销毁
*/
destroy() {
super.destroy()
this.stop()
this.clear()
}
}
/**
* 导出Queue
* @export
*/
export default Queue