Skip to content

并发任务控制

js
// 实现并发请求,每次最多请求3次
class asyncRequest {
    cur = 0
    maxNums = 0
    tasks = []

    constructor (tasks, maxNums) {
        this.tasks = tasks
        this.maxNums = maxNums
        this.cur = 0
    }

    addTask(tasks) {
        this.tasks = this.tasks.concat(tasks)
    }

    async _run() {
        if (this.cur < this.maxNums) {
            let task = this.tasks.shift()
            if (task) {
                this.cur++
                await task().then(() => {
                    this.cur--
                    this._run()
                })
            }
        }
    }

    start() {
        let i = 1
        while (i <= this.maxNums) {
            this._run()
            i++
        }
    }
}

// 测试
let p1 = () => new Promise((res) => {
    setTimeout(() => {
        console.log('p1')
        res()
    }, 2000)
})
let p2 =() => new Promise((res) => {
    setTimeout(() => {
        console.log('p2')
        res()
    }, 2000)
})

let p3 = () => new Promise((res) => {
    setTimeout(() => {
        console.log('p3')
        res()
    }, 2000)
})

let aR = new asyncRequest([p1, p2, p3], 3)
aR.addTask([p1,p2])
aR.addTask([p3,p1])
aR.start()

测试请求的接口时长

要求编写函数,传入请求的URL、请求次数、请求并发数,返回请求的平均时长。

js
async function testQueryTime({ url, allCount, concurrency }) {
    let completed = 0;
    const allTime = [];

    // 创建请求函数(使用setTimeout模拟)
    const sendRequest = () => {
        return new Promise(resolve => {
            const startTime = Date.now();
            setTimeout(() => {
                const endTime = Date.now();
                resolve(endTime - startTime);
            }, 2000)
        });
    };
    
    const worker = async () => {
        while (completed < allCount) {
            const index = completed++;
            const time = await sendRequest();
            console.log('请求时长', time)
            allTime[index] = time;
        }
    }

    // 创建工作线程
    const workers = Array(concurrency).fill().map(() => worker());

    await Promise.all(workers);
    return allTime.reduce((a, b) => a + b, 0) / allTime.length;
}

testQueryTime({url: 'xx', allCount: 10, concurrency: 3}).then(res => {
    console.log('平均时长', res)
})