Which timer fires first?

Each input line is a job: a label and a delay in milliseconds. Start every job at once, and print each label when its timer fires.

What to build

A program that runs jobs together, and knows when all of them have finished.

Requirements

  • Make a wait(ms) function that returns a promise.
  • Start a timer for every job at the same time.
  • When a job's timer fires, print its label.
  • After every job has finished, print all done, using await Promise.all(...).

Input

Several lines, each LABEL DELAY.

Output

The labels in the order the timers fire, then all done.

Constraints

There are from 1 to 50 lines, and each delay is from 0 to 10000.

Example

Input:

slow 300
fast 100

Output:

fast
slow
all done

Why it works

Each job is started without waiting for the last one, so the short delay finishes first. Promise.all gives a single promise that settles when every job has finished, and that is the moment to print the last line.

Examples

Example 1 · Input
slow 300
fast 100
Expected output
fast
slow
all done
Example 2 · Input
a 0
b 0
Expected output
a
b
all done

Hints

Hint 1

wait(ms) can be new Promise((resolve) => setTimeout(resolve, ms)).

Hint 2

Start every timer first, then await Promise.all of all the promises.

Hint 3

Timers with the same delay fire in the order they were set.

Solution

Show one correct solution (try it yourself first)
function wait(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

async function main() {
  const jobs = [];
  let line = prompt();
  while (line !== null) {
    const [label, delay] = line.split(" ");
    jobs.push({ label, delay: Number(delay) });
    line = prompt();
  }
  await Promise.all(jobs.map((job) => wait(job.delay).then(() => console.log(job.label))));
  console.log("all done");
}

main();

Lesson: Asynchronous JavaScript: event loop, promises, async/await →