牛客网题目:
    JS实现一个带并发限制的异步调度器Scheduler,保证同时运行的任务最多有两个。完善代码中Scheduler类,使得以下程序能正确输出。

    1. // 基础代码
    2. class Scheduler {
    3. add(promiseCreator) { ... }
    4. // ...
    5. }
    6. const timeout = (time) => new Promise(resolve => {
    7. setTimeout(resolve, time)
    8. })
    9. const scheduler = new Scheduler()
    10. const addTask = (time, order) => {
    11. scheduler.add(() => timeout(time)).then(() => console.log(order))
    12. }
    13. addTask(1000, '1')
    14. addTask(500, '2')
    15. addTask(300, '3')
    16. addTask(400, '4')
    17. // output: 2 3 1 4
    18. // 一开始,1、2两个任务进入队列
    19. // 500ms时,2完成,输出2,任务3进队
    20. // 800ms时,3完成,输出3,任务4进队
    21. // 1000ms时,1完成,输出1
    22. // 1200ms时,4完成,输出4

    答案:

    1. class Scheduler {
    2. constructor() {
    3. this.taskArr = []
    4. this.count = 0
    5. }
    6. add(promiseCreator) {
    7. return new Promise((resolve, reject) => {
    8. this.taskArr.push({promiseCreator, resolve})
    9. this.run()
    10. })
    11. }
    12. run() {
    13. if(this.taskArr.length && this.count < 2) {
    14. this.count ++
    15. let {promiseCreator, resolve} = this.taskArr.shift()
    16. Promise.resolve(promiseCreator()).then(() => {
    17. resolve()
    18. this.count --
    19. this.run()
    20. })
    21. }
    22. }
    23. }
    24. const timeout = (time) => new Promise(resolve => {
    25. setTimeout(resolve, time)
    26. })
    27. const scheduler = new Scheduler()
    28. const addTask = (time, order) => {
    29. scheduler.add(() => timeout(time))
    30. .then(() => console.log(order))
    31. }
    32. addTask(1000, '1')
    33. addTask(500, '2')
    34. addTask(300, '3')
    35. addTask(400, '4')
    36. // output: 2 3 1 4
    37. // 一开始,1、2两个任务进入队列
    38. // 500ms时,2完成,输出2,任务3进队
    39. // 800ms时,3完成,输出3,任务4进队
    40. // 1000ms时,1完成,输出1
    41. // 1200ms时,4完成,输出4
    42. // 保证同时运行的任务最多有两个a