Wait for it: Implementing a sleep() function in JS
Tags: javascript, codenewbie, beginners, react
Published: 2021-06-03 21:43:05

[In my last blog entry](https://dev.to/dsasse07/algorithm-practice-champagne-tower-explanation-414h), I had created a visualizer to model an approach to solving a Leetcode algorithm problem. I had planned to create a second entry in that series this week, however I ran into an obstacle:

_How do I slow down the operation speed of a function to the point where I could create visual models and allow the viewer time to process them before it updated to the next step?_

Most program languages have a `sleep` function/method that can be invoked to delay the next operation in a function. For example, Ruby has `sleep(1000)` and Python has `time.sleep(1)` to "pause" operation for 1 second, but there is no direct correlate in Javascript.

## setTimeout and setInterval
Asynchronous actions in Javascript can usually call upon one of these two functions. [setTimeout](https://www.w3schools.com/jsref/met_win_settimeout.asp) allows us to wait a specified amount of time before invoking a new callback function with [setInterval](https://www.w3schools.com/jsref/met_win_setinterval.asp) operating similarly except the delay will reset and continue repeating.

For the purposes of slowing down operation for something like a `while` loop, neither of these are directly helpful since they delay the invocation of a new action rather than the delay the original function in which they were called.

## Incorporating Promises
In Javascript, a [Promise object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) represents the eventual completion of an action. For example, if you have ever worked with an API call and made a request to the server, that request returns a "pending" Promise that will ultimately become "resolved" or "rejected". When creating a new Promise object, we can pass in two callback functions as arguments. The first argument is the function that will be invoked when the Promise is resolved, and the second (optional) is invoked if the Promise is rejected.

### Example: 
```js
const sleep = (ms) => {
  return new Promise((resolve) => setTimeout(resolve, ms));
};
```

In the example above, the function accepts a single parameter which will reflect the time in milliseconds that we would like the function to sleep for. We then create a new Promise object and use `setTimeout` in the callback function for the resolution of the Promise. We do not need a callback for the Promise reject here, as this will never arise in this use case.

`setTimeout` itself takes in two arguments: a callback function and a duration in milliseconds in which to delay invoking the callback. For the delay, we simply pass the `ms` parameter of the sleep function. For the callback, we will use the resolve action of the Promise. This means that the state of the Promise will not be set to resolved until that delay time has passed.

## Usage

With the `async`/`await` keywords in our functions, we can tell a function to "await" the resolution of a Promise before continuing its next action. If we combine this with a setTimeout action, we can effectively create a `sleep()` function in Javascript.

Example:

```js
const sleep = (ms) => {
  return new Promise((resolve) => setTimeout(resolve, ms));
};

const action = async () => {
    for (let i = 1; i < 5; i++){
        console.log(`Round ${i}`)
        console.log('Waiting for 500ms')
        await sleep(500)
        console.log('Posting')
    }
}
```
In this example, the final operation of each iteration will not run until the promise from the `sleep()` function has been resolved.

![Sleep Example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uwzcrintrj0kzgaeq7h1.gif)

Initially the uses for this action compared a "regular" timeout or interval may seem limited. However, this allowed me to solve my initial challenge of trying to visualize the progress of an algorithm solution to create a visualizer. Normally, the speed at which a function runs would make it impossible for a viewer to see the incremental changes in values or current positions in a traversal. However, if we render a component, and provide a brief `sleep` in each iteration it allows the user to view the changes occurring at each step.

For example, we can visualize a depth first search process through a grid to map out the "land area" of islands in an "ocean":

![Island Example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/far0edws3l49o1wyeyjg.gif)

Hopefully this implementation of a sleep function opens up new options for you in your coding. More information on the mapping algorithm above and the visualizer itself will come next week!