Getting Sleep() with Promises in JS
Tags: asynchronous, promises, javascript
Published: 2020-02-14 13:29:16

---
title: Getting Sleep() with Promises in JS
published: true
date: 2019-11-04 22:40:01 UTC
tags: asynchronous,promises,javascript
canonical_url: 
---
*__Note__: this post was originally published on [Medium](https://medium.com/@noamsauerutley/finding-the-top-n-per-group-with-sql-8c9a427a9fa1) in November, 2019*


![a small dog sitting under a blanket and looking at an alarm clock](https://cdn-images-1.medium.com/max/480/1*PZMeXFJzCJr3IE7g3j-ZfA.gif)

Recently, I started building a very basic single page app to illustrate [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) usage in a cute and simple way.

![a dachshund putting a tennis ball into a ball-throwing machine](https://cdn-images-1.medium.com/max/250/1*pSprzPedpIVMYHW5RGejpw.gif)

![Header: “Welcome to Dog Fetch!”. Yellow button: “Throw the ball!”. smaller text: “You have thrown the ball for: No dogs yet!”](https://cdn-images-1.medium.com/max/783/1*Z2aBcVI3fjHCJ0PBb3wt2A.png)

![a large brown dog jumping to catch a ball](https://cdn-images-1.medium.com/max/480/1*IqFn91pYg2Ss5ImNM_PtXg.gif)

When the user clicks a button styled like a tennis ball, a new dog image is fetched from the [Dog API](https://dog.ceo/dog-api/), and given a name fetched from the [Namey API](https://namey.muffinlabs.com/).

![a yellow labrador retriever jumping into a pile of leaves of fetch a ball](https://cdn-images-1.medium.com/max/350/1*1e6THth06sEuMYN0LaJaYg.gif)

The dog’s image is loaded onto the page, and with each fetch, a name is added onto a list of fetched dogs.

![Header: “Look who it is!”. Below the header, a hound dog looking at the camera.](https://cdn-images-1.medium.com/max/900/1*YmPp2OrBlHSpcqX_aFysSg.png)

However, once a few dogs were fetched, the [document](https://www.w3schools.com/jsref/dom_obj_document.asp) content stretched down quite far, and required a bit of scrolling to view. I decided to add a handy little link in the page footer which would scroll the viewer right up to the top, and re-fire the fetch cycle.


```

    function scrollAndThrow(){
        //smooth scroll back to top left corner of window
        window.scroll({
            top: 0, 
            left: 0, 
            behavior: 'smooth' 
           })
        // then click the button to trigger a new round of fetch   
        button.click()
    }
```
We can just scroll up the window, then trigger a new[click event](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click) on the button we’ve assigned to the variable  **_button_**.

However, the the combo of the page scrolling up and the image fetch simultaneously re-firing looks pretty messy.

![the page awkwardly reloading as it autoscrolls up](https://cdn-images-1.medium.com/max/480/1*4Z41QWEMYXG7iCGPc17F-g.gif)<figcaption>Yikes.</figcaption>

I wanted a way to slow things down, so the user would only see one thing happening on the page at a time.

I knew that if I could just pause for half a second between the scroll and the API Fetch, everything would look much smoother.

Suddenly, I missed Ruby’s [**_sleep_**](https://apidock.com/ruby/Kernel/sleep) method. It was so [nice](https://en.wiktionary.org/wiki/MINASWAN) to be able to schedule events to the exact time I wanted them to run!

![a puppy stretching in its sleep](https://cdn-images-1.medium.com/max/300/1*CN5z1yOQSEHrtS-5FBOkAg.gif)

I decided there had to be a way to construct my own dupe of that handy little method.

![a dachshund wearing a hard hat and riding on a toy truck](https://cdn-images-1.medium.com/max/250/1*FOggOhrunoyRldm4aUY-Ww.gif)

If you’re not familiar with JS [Promises](https://developers.google.com/web/fundamentals/primers/promises), it’s important to first understand that while Javascript is [single-threaded](https://en.wikipedia.org/wiki/Thread_(computing)) (meaning it can only process one [**_statement_**](https://www.w3schools.com/js/js_statements.asp) at a time), it is also [**_asynchronous_**](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Introducing) (meaning it can start processing a new statement before the previous statement has resolved, allowing it to multitask time-consuming processes in the background.).

![a dog digging a big hole, kicking sand back onto another dog that is sleeping](https://cdn-images-1.medium.com/max/446/1*RcbHviozBBiqYZ2wVMzXfA.gif)

Javascript uses Promises to track the resolution of those background processes, allowing us to set certain statements to run only when a time-consuming process has resolved and returned its completed result.

![a small dog sitting up on its hind legs and looking out the front door as if waiting for someone](https://cdn-images-1.medium.com/max/250/1*NhGha_udiTpGSWoW5MtQqg.gif)

This is great for handling fetch requests and other time consuming processes, but it also gives us a way to tell our app to wait to process certain statements until exactly when we want them to be run.

I realized that I could exploit this functionality by building a Promise around Javascript’s built-in [**_setTimeout_**](https://www.w3schools.com/jsref/met_win_settimeout.asp)**_()_** method.

![a sad looking puppy sitting in the corner with the caption “He’s in time out”](https://cdn-images-1.medium.com/max/220/1*mbLAy1wFOk7Rv1lfuavXDA.gif)

### Let’s make a promise:

[**_setTimeout()_**](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout) takes in two parameters:

> 1: A function to be executed after the timer expires.

> 2: The time, in milliseconds (thousandths of a second), the timer should wait before the specified function or code is executed. If this argument is omitted, a value of 0 is used, meaning execute “immediately”, or more accurately, as soon as possible. Note that in either case, the actual delay may be longer than intended

```
return new Promise(resolve => setTimeout(resolve, ms))
      
```
We can create a new Promise, and tell setTimeout to pass the Promise resolve statement as setTimeout’s first parameter. setTimeout will delay for **_ms_** milliseconds, then **_resolve_** the promise. If we throw this in a function, we now have a handle little delay function ready to go!

```
 function sleep(ms) {
        // add ms millisecond timeout before promise resolution
        return new Promise(resolve => setTimeout(resolve, ms))
      }
```
Great! Now we made our replacement for Ruby’s [sleep](https://apidock.com/ruby/Kernel/sleep) method.

Now let’s put it to use.

I decided to take advantage of one of [ES6](http://es6-features.org/)’s fresher bits of syntax for [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) handling: [Async/await](https://javascript.info/async-await).

```
  async function delayedClick(){
        // await sleep function promise
        await sleep(700)
        // once resolved, click button
        button.click()
    }
```

**_delayedClick()_** knows from the get that it’s awaiting a promise resolution. We’re using our brand new **_sleep()_** function as the awaited promise, passing in our desired number of milliseconds (in this case, **700ms** , or **7/10ths of a second** ). Once that promise resolves, we can enter the action we want **_delayedClick()_** to enact. In this case, we’re going to click the button that re-starts the fetch and display cycle.

Now that we have our delay and desired action plugged into a method, we can plug **_delayedClick()_** into our existing **_scrollAndThrow()_** method as a replacement to **_button.click()_** to slow things down and clean up the onscreen process.

```

    function scrollAndThrow(){
        // smooth scroll back to top left corner of window
        window.scroll({
            top: 0, 
            left: 0, 
            behavior: 'smooth' 
           })
        // use sleep function promise to initiate 700 millisecond delay
        // then click button and initiate new fetch cycle
        delayedClick()
    }
```
The result: no more jaggedy mid-scroll fetch return and image load!

![the app smoothly scrolling up, then reloading](https://cdn-images-1.medium.com/max/480/1*LUPGETL9Zn5xMjZqtQnvGA.gif)<figcaption>Much nicer!</figcaption>

Sometimes, it’s just good to get some sleep!

![a cute puppy falling asleep](https://cdn-images-1.medium.com/max/220/1*YvcchgBbhm_Iejp-8dUDig.gif)

#### Notes:

- Want to fetch a dog? Check out the repo [here](https://github.com/noamsauerutley/doggie-fetch).
- For dog pics, I used the Dog API: [https://dog.ceo/dog-api/](https://dog.ceo/dog-api/) .
- for random first names, I used the muffinlabs Namey API: [https://namey.muffinlabs.com/](https://namey.muffinlabs.com/)
- Using [Node.js](https://nodejs.org/en/)? Turns out that there’s a handy little module built by [Wes Bos](https://wesbos.com/) that keeps this functionality ready to go for you. Check out Waait: [https://www.npmjs.com/package/waait](https://www.npmjs.com/package/waait).