js异步编程-题目29 实现异步任务执行器 AsyncWorker

文章目录

  • 题目内容
    • 代码区
  • 思路
    • 答案

整理下初学时做过的js基础编程题目和大家分享以下,如果大家觉得有用,别忘了点一下赞哦

题目内容

/**
 * Q: 实现一个异步任务执行器 AsyncWorker
 *
 * 此 AsyncWorker: 最多只能同时执行 capacity
 * 个异步任务. 若正在执行的任务数达到 capacity,
 * 则新加入的任务需要等待其中一个正在执行的任务完
 * 成后才能被执行.
 */

代码区

class AsyncWorker {
    constructor(capacity) {
        this.capacity = capacity
    }

    exec(task) {
        // show me the code, please delete the following line.
        throw new Error('not implemented')
    }
}

// TEST
async function testAsyncWorker() {
    const start = Date.now()
    const createTask = (timeout, error) => {
        return () =>
            new Promise((resolve, reject) => {
                setTimeout(() => {
                    if (error) {
                        reject(error)
                    } else {
                        resolve(timeout)
                    }
                }, timeout)
            })
    }
    const worker = new AsyncWorker(2)
    const tasks = [
        {
            status: 'fulfilled',
            value: 100,
            idealCost: 100,
            task: worker.exec(createTask(100)),
        },
        {
            status: 'fulfilled',
            value: 201,
            idealCost: 200,
            task: worker.exec(createTask(201)),
        },
        {
            status: 'rejected',
            reason: 'REJECTED',
            idealCost: 300,
            task: worker.exec(createTask(202, 'REJECTED')),
        },
        {
            status: 'fulfilled',
            value: 203,
            idealCost: 400,
            task: worker.exec(createTask(203)),
        },
        {
            status: 'fulfilled',
            value: 300,
            idealCost: 600,
            task: worker.exec(createTask(300)),
        },
    ]
    
    for (let index = 0; index < tasks.length; index++) {
        const t = tasks[index]
        let result
        try {
            const value = await t.task
            result = { status: 'fulfilled', value }
        } catch (e) {
            result = { status: 'rejected', reason: e }
        }
        const realCost = Date.now() - start
        const idealCost = (realCost - (realCost % 100)) | 0
        if (idealCost !== t.idealCost) {
            throw new Error(
                `unexpected time cost: ${idealCost}, expected is ${t.idealCost} for ${index}`
            )
        }
        if (result.status !== t.status) {
            throw new Error(`unexpected status ${result.status} for ${index}`)
        }
        if (
            t.status === 'fulfilled' &&
            result.status === 'fulfilled' &&
            result.value !== t.value
        ) {
            throw new Error(
                `unexpected fulfilled value ${result.value}, expected is ${t.value} for ${index}`
            )
        }
        if (
            t.status === 'rejected' &&
            result.status === 'rejected' &&
            result.reason !== t.reason
        ) {
            throw new Error(
                `unexpected rejected reason ${result.reason}, expected is ${t.reason} for ${index}`
            )
        }
    }
}

思路

待续...

答案

class AsyncWorker {
    constructor(capacity) {
        this.capacity = capacity
        this.taskNum = 0 // 当前任务数量
        this.taskPool = [] // 回调函数队列池
    }

    async exec(task) {
        return new Promise(async (resolve, reject) => {
            const execute = async () => {
                this.taskNum++;  // 增加正在执行的任务数
                try {
                    const result = await task();  // 执行任务并等待结果
                    resolve(result);             // 成功时解析 Promise
                } catch (error) {
                    reject(error);               // 失败时拒绝 Promise
                } finally {
                    this.taskNum--;  // 减少正在执行的任务数
                    this.processQueue();  // 处理等待队列中的任务
                }
            };

            if (this.taskNum < this.capacity) {
                execute();  // 如果有可用的执行容量,立即执行任务
            } else {
                this.taskPool.push(execute);  // 否则将任务添加到等待队列
            }
        });
    }

    processQueue() {
        if (this.taskPool.length > 0 && this.taskNum < this.capacity) {
            const task = this.taskPool.shift();  // 从等待队列中获取下一个任务
            task();  // 执行等待的任务
        }
    }
}

你可能感兴趣的:(#,js编程题,javascript,前端,开发语言)