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

2019-07-17 22:32:01 +08:00
 chashao
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

   






1639 次点击
所在节点    问与答
11 条回复
chashao
2019-07-17 22:32:43 +08:00
这道题的要求是并行执行,并行最多两个任务。
meszyouh
2019-07-18 08:38:57 +08:00
看起来还于 timeout 有关?总是接在时间最少的部分?
kamilic
2019-07-18 10:01:28 +08:00
```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;
```

昨晚一时兴起写了一下,希望对你有帮助。。
kamilic
2019-07-18 10:02:21 +08:00
??不支持 md 的?
zbinlin
2019-07-18 10:09:27 +08:00
这是面试题吗?如果是的话,我肯定会挂的 :(

paste.ubuntu.com/p/Rm6dDmWxkN/
zbinlin
2019-07-18 10:10:45 +08:00
chashao
2019-07-18 10:45:52 +08:00
@meszyouh 是的,timeout 最小的任务最先完成,之后的任务就能添加进来。
chashao
2019-07-18 10:46:20 +08:00
@zbinlin 是字节跳动的校招题
WhoAmIAndwhoAreU
2019-07-18 10:51:43 +08:00
插眼
meszyouh
2019-07-18 13:18:06 +08:00
autoxbc
2019-07-19 23:19:22 +08:00
收到 #6 @zbinlin 答案的启发,写了个简化版,应该更好理解一点

https://gist.github.com/autoxbc/410c381aca4772736dfe22f6b4590c46

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/583939

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX