首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
V2EX  ›  问与答

一道 promise 的题目,求大佬解答

  •  
  •   chashao · 39 天前 · 655 次点击
    这是一个创建于 39 天前的主题,其中的信息可能已经有所发展或是发生改变。
    class Scheduler {
        add(promiseCreator) {
              // 需要实现
        }
    }
    
    const timeout = (time) => new Promise(resolve => {
        console.log('in timeout:', time);
        setTimeout(resolve, time)
    });
    
    const scheduler = new Scheduler();
    
    const addTask = (time, order) => {
        scheduler.add(() => timeout(time))
                 .then(() => console.log(order))
    };
    
    addTask(1000, '1')
    addTask(500, '2')
    addTask(300, '3')
    addTask(400, '4')
    // output: 2 3 1 4
    // 一开始,1、2 两个任务进入队列
    // 500ms 时,2 完成,输出 2,任务 3 进队
    // 800ms 时,3 完成,输出 3,任务 4 进队
    // 1000ms 时,1 完成,输出 1
    // 1200ms 时,4 完成,输出 4
    
       
    
    
    
    
    
    
    
    11 回复  |  直到 2019-07-19 23:19:22 +08:00
        1
    chashao   39 天前
    这道题的要求是并行执行,并行最多两个任务。
        2
    meszyouh   39 天前 via Android
    看起来还于 timeout 有关?总是接在时间最少的部分?
        3
    kamilic   39 天前   ♥ 1
    ```javascript
    class Scheduler {
    constructor() {
    this.__maxQueueSize = 2;
    this.__runningJobs = [];
    this.__pendingQueue = [];
    }

    get isJobsFull() {
    return this.__maxQueueSize <= this.__runningJobs.length;
    }

    static jobWrapper(promiseCreator) {
    Scheduler.__jobId += 1;
    const id = Scheduler.__jobId;
    const wrappedPromise = promiseCreator().then((result) => {
    return {
    id,
    result
    };
    });
    wrappedPromise.__jobId = id;
    return wrappedPromise;
    }

    removeFinishedJob(id) {
    console.log(`remove ${id}`);
    this.__runningJobs = this.__runningJobs.reduce((curr, job) => {
    if (job.__jobId !== id) {
    curr.push(job);
    }
    return curr;
    }, []);
    console.log(this.__runningJobs);
    }

    async add(promiseCreator) {
    if (!this.isJobsFull) {
    const job = Scheduler.jobWrapper(promiseCreator);
    this.__runningJobs.push(job);
    const {result, id} = await job;
    this.removeFinishedJob(id);
    return result;
    } else {
    this.__pendingQueue.unshift(promiseCreator);
    await Promise.race(this.__runningJobs);
    if (this.__pendingQueue.length > 0) {
    return this.add(this.__pendingQueue.pop());
    }
    }
    }
    }

    Scheduler.__jobId = 0;
    ```

    昨晚一时兴起写了一下,希望对你有帮助。。
        4
    kamilic   39 天前
    ??不支持 md 的?
        5
    zbinlin   39 天前
    这是面试题吗?如果是的话,我肯定会挂的 :(

    paste.ubuntu.com/p/Rm6dDmWxkN/
        6
    zbinlin   39 天前   ♥ 1
        7
    chashao   39 天前
    @meszyouh 是的,timeout 最小的任务最先完成,之后的任务就能添加进来。
        8
    chashao   39 天前
    @zbinlin 是字节跳动的校招题
        9
    WhoAmIAndwhoAreU   39 天前
    插眼
        11
    autoxbc   37 天前
    收到 #6 @zbinlin 答案的启发,写了个简化版,应该更好理解一点

    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3936 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 21ms · UTC 06:56 · PVG 14:56 · LAX 23:56 · JFK 02:56
    ♥ Do have faith in what you're doing.