JavaScript Concurrency: Sleep
Welcome to the Sleep lesson!
This lesson is shown as static text below. However, it's designed to be used interactively. Click the button below to start!
Many code examples in this course have contained code that "sleeps" (waits for some amount of time while doing nothing).
>
console.log('Sleeping...');new Promise(resolve => setTimeout(resolve, 1500)).then(() => {console.log('Awake!');});async console outputWe can write a
sleepfunction that does this for us. It should work just like the example above, but wrapped in a function.Here's a code problem:
Implement the
sleep(ms)function. This function should use the promise constructor (new Promise) to return a promise that resolves after the specified number of milliseconds. Inside the promise, usesetTimeoutto delay calling theresolvefunction.function sleep(ms) {return new Promise(resolve => setTimeout(resolve, ms));}// Get the current timestamp in ms.const startTime = new Date().getTime();// Sleep for 1.5 seconds.sleep(1500).then(() => {// Compute the number of elapsed ms.return new Date().getTime() - startTime;}).then(elapsed => {/* Have between 1 and 2 seconds elapsed? (We can only check* approximately because the actual timing will vary on each run.) */return elapsed >= 1000 && elapsed <= 2000;});Async Result:
- Goal:
{fulfilled: true}- Yours:
{fulfilled: true}
Here's a code problem:
The following code pushes
1and2into an array. Currently, it pushes2first, then1. Your goal is to get them to push in order, so the array ends up holding[1, 2].You can't modify the
array.push(1)call, and you can't modify the order of the calls. Instead, use thesleepfunction to delay thearray.push(2)call. You'll have to delay it by more than 500 ms. (We recommend 1000 ms. If you schedule it for, say, 501 ms, then minor variability with how the code is scheduled by the computer could affect the results.)const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));const array = [];sleep(1000).then(() => array.push(2));sleep(500).then(() => array.push(1));array;Async Result:
- Goal:
[1, 2]
- Yours:
[1, 2]
We'll see
sleepin future lessons, so we want to keep it short. Writing it as an arrow function lets us reduce it to one line.>
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));Now that we have a nice, compact
sleepfunction, we can use it to clean up the code from our first example.- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
console.log('Sleeping...');sleep(1500).then(() => {console.log('Awake!');});async console output When possible, try to separate code that uses the promise constructor (
new Promise) from the rest of the code, like we did here by hiding thenew Promiseinside ofsleep. That keeps the rest of the code simpler: it can just callsleepwithout worrying about the promise constructor.Like all promise code,
sleepworks with async/await. And as usual, the async/await version looks much cleaner because it avoids the syntactic noise of promises.- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
async function run() {console.log('Sleeping...');await sleep(1500);console.log('Awake!');}run();async console output sleepis a very simple function, but most systems end up with something like it eventually. It can be used to delay visual feedback, to wait before retrying a failed operation, or to wait for something to happen in an automated test. (Execute Program uses a similar function in its email sending code. Our email provider occasionally returns an error, and in that case we sleep for one second, then try again.)