QPS的异步函数队列

因为http请求的QPS最大在4-10之间,但是真实业务居然需要同时发送15个请求,就出现了问题。所有分享一个异步函数队列的 方法。话不多说上代码!

interface initOptions {
    QPS?: number
}
class asyncQueue {
    QPS = 4
    queueList: Array<{
        id: string,
        fn: Promise
    }> = []
    pending = 0
    result: { [key: string]: any } = {}
    constructor(options?: initOptions) {
        const { QPS } = options || {}
        this.QPS = QPS || 4
    }

    /**
     * New queue record
     * @param asyncFn Async execution method
     */
    add(asyncFn:Promise) {
        const id = Date.now() + '_' + parseInt(Math.random() * 100000 + '')
        this.queueList.push({
            id,
            fn: asyncFn
        })
        this.exec()
        return this.queryResult(id)
    }

    /**
     * Query Async queue execution results
     * @param id Query ID
     */
    queryResult(id: string): Promise {
        return new Promise(resolve => {
            const fn = (id: string, callback?: Function) => {
                const data = this.result[id]
                if (data && callback) {
                    delete this.result[id]
                    callback(data)
                    return
                }
                setTimeout(() => {
                    fn(id, callback)
                }, 300)
            }
            fn(id, resolve)
        })
    }

    /**
     * Execute Queue Functions
     */
    exec() {
        const QPS = this.QPS
        if (this.pending >= QPS || !this.queueList || this.queueList.length === 0) return
        this.queueList.splice(0, QPS - this.pending).forEach(item => {
            const fn = item.fn
            const id = item.id
            this.pending += 1;
            fn.then(result => {
                this.result[id] = result
            }).finally(() => {
                this.pending -= 1
                this.exec()
            })
        });
    }
}

/**
 * Test functions
 * @param time
 */
const testAsyncFn = (time:number):Promise=>{
    return new Promise(resolve=>{
        setTimeout(()=>{
            console.log('runtimr',time)
            resolve(time);
        },time)
    })
}

/**
 * Executive 100 times
 */
const queue = new asyncQueue()
for (let index = 0; index < 100; index++) {
    queue.add(testAsyncFn(Math.random() * 1000)).then(result=>{
        console.log(result)
    })
}

喜欢的点个赞哦。

你可能感兴趣的:(QPS的异步函数队列)