并发任务控制【JavaScript】

根据下面这段代码实现一个构造函数SuperTask

  • 里面有一个add方法
  • 返回一个Promise
  • 根据代码返回的结果可知,任务并发数为2
function timeout(time) {
    return new Promise((resolve, reject) => {
        setTimeout(reject, time);
    })
}

const superTask = new SuperTask()

function addTask(time, name) {
    superTask
        .add(() => timeout(time))
        .then(() => {
            console.log(`任务${name}完成`)
        }, () => {
            console.log(`任务${name}失败`)
        })
}

// 由这个可知 任务并发数为2
addTask(1000, 1) // 10s后输出 任务1已完成
addTask(500, 2) // 5s后输出 任务2已完成
addTask(300, 3) // 8s后输出 任务3已完成
addTask(400, 4) // 10s后输出 任务4已完成
addTask(500, 5) // 15s后输出 任务5已完成

代码实现如下

1.代码实现需要的已知条件 parallelCount并发任务数 tasks任务队列 runningCount正在执行的任务

2.add方法返回一个Promise

3.实现一个 _run方法,这个方法类似叫号

  •         执行了一个任务后需要调用这个函数是否还有剩余的执行空间
  •         然后就是一个任务进入任务队列后也需要调用这个函数看是否有剩余的执行空间

4.有一个细节,就是任务队列中传递三个参数{task,resolve,reject},这样的话在_run函数中执行task任务后需要拿到任务成功后的成功回调和失败回调

class SuperTask {
    constructor(parallelCount = 2) {
        this.parallelCount = parallelCount // 并发任务数
        this.tasks = [] // 正在排队的任务
        this.runningCount = 0 // 正在执行的任务
    }
    add(task) {
        return new Promise((resolve, reject) => {
            // 加入到任务队列
            this.tasks.push({
                task,
                resolve,
                reject
            })
            this._run()
        })
    }
    // 询问可以取出一个任务进行处理
    _run() {
        while (this.tasks.length && this.runningCount < this.parallelCount) {
            const { task, resolve, reject } = this.tasks.shift()
            task().then(resolve, reject).finally(() => {
                this.runningCount--
                this._run()
            })
            this.runningCount++
        }
    }
}

附源码:

function timeout(time) {
    return new Promise((resolve, reject) => {
        setTimeout(reject, time);
    })
}



const superTask = new SuperTask()

function addTask(time, name) {
    superTask
        .add(() => timeout(time))
        .then(() => {
            console.log(`任务${name}完成`)
        }, () => {
            console.log(`任务${name}失败`)
        })
}

// 由这个可知 任务并发数为2
addTask(1000, 1) // 10s后输出 任务1已完成
addTask(500, 2) // 5s后输出 任务2已完成
addTask(300, 3) // 8s后输出 任务3已完成
addTask(400, 4) // 10s后输出 任务4已完成
addTask(500, 5) // 15s后输出 任务5已完成

// 实现SuperTask
class SuperTask {
    constructor(parallelCount = 2) {
        this.parallelCount = parallelCount // 并发任务数
        this.tasks = [] // 正在排队的任务
        this.runningCount = 0 // 正在执行的任务
    }
    add(task) {
        return new Promise((resolve, reject) => {
            // 加入到任务队列
            this.tasks.push({
                task,
                resolve,
                reject
            })
            this._run()
        })
    }
    // 询问可以取出一个任务进行处理
    _run() {
        while (this.tasks.length && this.runningCount < this.parallelCount) {
            const { task, resolve, reject } = this.tasks.shift()
            task().then(resolve, reject).finally(() => {
                this.runningCount--
                this._run()
            })
            this.runningCount++
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值