Write createScheduler(). It returns an object with one method, add(task, delay), that schedules task (a function called with no arguments) to run delay ms later, and returns a promise of what task returns.
Tasks run one at a time, in the order they were added. A task's delay starts when the task before it has finished; if that task returned a promise, when the promise has settled. When nothing is running or waiting, the delay starts right away.
If a task throws or returns a rejected promise, the promise from its add rejects with that error, and the next task runs as usual. If it returns a promise that resolves, the promise from add resolves with that value.
const scheduler = createScheduler();
scheduler.add(() => console.log("a"), 1000); // logs "a" at 1000 ms
scheduler.add(() => console.log("b"), 500); // logs "b" at 1500 ms
scheduler.add(() => console.log("c"), 0); // logs "c" at 1500 ms, after "b"
const clock = useFakeTimers();
const scheduler = createScheduler();
const task = spy();
scheduler.add(task, 100);
await clock.tickAsync(99);
expect(task).toHaveBeenCalledTimes(0);
await clock.tickAsync(1);
expect(task).toHaveBeenCalledTimes(1);
const clock = useFakeTimers();
const start = clock.now();
const log = [];
const scheduler = createScheduler();
scheduler.add(() => log.push("a at " + (clock.now() - start)), 100);
scheduler.add(() => log.push("b at " + (clock.now() - start)), 50);
scheduler.add(() => log.push("c at " + (clock.now() - start)), 0);
await clock.tickAsync(1000);
expect(log).toEqual(["a at 100", "b at 150", "c at 150"]);
const clock = useFakeTimers();
const start = clock.now();
const log = [];
const scheduler = createScheduler();
scheduler.add(() => new Promise((resolve) => setTimeout(resolve, 200)), 100);
scheduler.add(() => log.push(clock.now() - start), 100);
await clock.tickAsync(1000);
expect(log).toEqual([400]);
const clock = useFakeTimers();
const start = clock.now();
const log = [];
const scheduler = createScheduler();
scheduler.add(() => log.push(clock.now() - start), 100);
await clock.tickAsync(500);
scheduler.add(() => log.push(clock.now() - start), 100);
await clock.tickAsync(1000);
expect(log).toEqual([100, 600]);
const clock = useFakeTimers();
const scheduler = createScheduler();
let results;
Promise.all([scheduler.add(() => "sync", 10), scheduler.add(async () => "async", 10)]).then((values) => {
results = values;
}, () => {});
await clock.tickAsync(100);
expect(results).toEqual(["sync", "async"]);
const clock = useFakeTimers();
const scheduler = createScheduler();
let error;
let result;
scheduler
.add(() => {
throw new TypeError("broken");
}, 100)
.catch((reason) => {
error = reason;
});
scheduler.add(() => "still runs", 100).then((value) => {
result = value;
}, () => {});
await clock.tickAsync(1000);
expect(error).toBeInstanceOf(TypeError);
expect(result).toBe("still runs");
Run tests runs every test on your code, here in your browser. The problem is solved when they all pass.
Ctrl + Enter runs the tests (⌘ + Enter on a Mac).
I'm here to help with Task scheduler with delays. I give hints, never the solution, so you get to solve it yourself. Ask for a hint, select code to ask about it, or press Ask Tuto why on a failing test.
Your first 3 answers need no account. for free to keep asking.