因为http请求的QPS最大在4-10之间,但是真实业务居然需要同时发送15个请求,就出现了问题。所有分享一个异步函数队列的 方法。话不多说上代码!
interface initOptions {
QPS?: number
}
class asyncQueue {
QPS = 4
queueList: Array<{
id: string,
fn: Promise<any>
}> = []
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<any>) {
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<any> {
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<any>=>{
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)
})
}
喜欢的点个赞哦。