WQueue.mjs

/**
 * 事件觸發器
 *
 * @returns {Object} 回傳事件觸發器物件,包含on與emit事件,on為註冊監聽事件,emit為觸發事件
 */
function EventEmitter() {

    //handles
    let handles = {}

    //on
    function on(eventName, callback) {
        if (!handles[eventName]) {
            handles[eventName] = []
        }
        handles[eventName].push(callback)
    }

    //emit
    function emit(eventName, ...arg) {
        if (handles[eventName]) {
            for (let i = 0; i < handles[eventName].length; i++) {
                handles[eventName][i](...arg)
            }
        }
    }

    return {
        on,
        emit,
    }
}


/**
 * 佇列處理器,單生產者單消費者模式,核心使用迭代器,具有消息堵塞與可限定同時處理上限數量功能
 *
 * @param {*} [opt={}] 輸入設定物件,預設{}
 * @param {Number} [opt.takeNumLimit=0] 輸入同時處理上限數量整數,預設0,代表無限制
 * @returns {Object} 回傳佇列處理器物件,包含事件on、push、get、cb。on為監聽事件,需自行監聽message事件,push為加入最新佇列消息,get為回傳當前最早佇列消息,cb為於message事件內回調使迭代器可取得下一個佇列消息
 */
function WQueue(opt = {}) {

    //default
    if (!opt.takeNumLimit) {
        opt.takeNumLimit = 0
    }

    //takeNum
    let takeNum = 0

    //qs
    let qs = []

    //ee
    let ee = new EventEmitter()

    //get, like iterator
    function get() {
        if (qs.length > 0) {

            //add takeNum
            takeNum += 1

            //take first
            let v = qs.splice(0, 1)[0]

            //r
            //let r = { value: v, done: false }
            let r = v

            return r
        }
        else {

            //r
            //let r = { value: undefined, done: true }
            let r = null

            return r
        }
    }
    ee.get = get

    //cb
    function cb() {

        //minu takeNum
        takeNum -= 1

        //emit
        if (qs.length > 0) {
            ee.emit('message', qs)
        }

    }
    ee.cb = cb

    //push
    function push(v) {

        //push
        qs.push(v)
        //console.log('push', qs)

        //emit
        if (opt.takeNumLimit <= 0 || takeNum < opt.takeNumLimit) {
            ee.emit('message', qs)
        }

    }
    ee.push = push

    return ee
}


export default WQueue