How to Detect Slow Internet Connection using JavaScript Async/await
Tags: webdev, javascript, react
Published: 2023-07-21 07:08:12


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lff9j9rx6lccptrjon85.png)

A **slow internet connection** is a mind-boggling experience in areas with slow internet connectivity. Sometimes you may have a highly performant app but your users’ internet connection hinders them from enjoying experience of  your website/web app. As such, it is important to build resilient applications that can quickly detect slow internet connection and notify the users promptly.


In JavaScript, a slow connection is a promise, or network request, that doesn't settle (resolve or reject) at a specific time and instead stays in the pending state indefinitely.  


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qeasre4ma81he16qn74k.png)
Remember there is a difference between a **slow network** (a promise that doesn't settle for a while) and a **no network** (a promise that settles with rejection), which typically returns error 404.


You can detect ‘no network’ using javascript offline and online events before making a request. Read this  [online/offline events article here](https://matemarschalko.medium.com/online-and-offline-events-with-javascript-d424bec8f43)

### Javascript is a single threaded and non-blocking language. 

Before I show you how to detect slow network on your website/web app, lets understand some JavaScript concepts; **Javascript is a single threaded and non-blocking language**. 


> It is **single threaded**  as it only processes one item at a time running a script line by line from top to bottom.

> It is a **non-blocking**  language in that when a Javascript interpreter encounters a lengthy process,  it doesn't wait for it to finish but instead it  delegates  a callback function that will handle when the process  completes  then continues to the next line.  

**Async/await** functions were introduced in JavaScript Ecmascript 2017 (ES2017), allowing  Javascript interpreter to use the keyword await inside a function to wait for an asynchronous operation to finish before moving on to the next line. In other words, async/await functions violate Javascript's non-blocking nature inside a function.

Lets now implement  single threaded and non-blocking nature of JS to detect slow network and here is how we will do it:


1. Determine the **time** to deem an internet connection as slow. (for our test we will use 500ms and throttle the network).Normally it could 30 seconds to a minute.
2. Declare an **async/await** data fetching  function .
3. Declare a `payload` variable  as null and later assign data from network request.
4. Set up a *setTimeout* method inside of async/await function just before `await` keyword, the method takes a callback function  that will check if a promise has settled at a given time by checking if payload is still null or received data from REST API.


  > Callback function is a function given to another function as an argument.it is a powerful feature in JavaScript and work horse of node JS. [Read More the difference between callback functions and high order functions](https://dev.to/kipyegonline/difference-between-callback-functions-and-high-order-functions-in-javascript-2bc8)


Our HTML code
```javascript
<button id="network-btn"  style="padding:0.5rem;
          background:rebeccapurple;
          color:white;
          border-radius:8px;
          outline:none;
          width: 150px;
          margin:5rem;"> Get Posts <button>
```

Our Javascript code
```javascript
const networkBtn = document.getElementById("network-btn");
let timeout = 500; // let assume its too slow at 500ms
let payload = null;
let clearTimer=null /* to clear our setTimeout, initialised as null */

const checkNetwork = () => {
  /* if after half a second payload  variable is still null, 
it means we are still awaiting the promise to settle */
  if (payload === null) {
    alert("Your internet connection is slow");
  }
};

async function getPosts() {
  
  let url = `https://jsonplaceholder.typicode.com/posts/`;
/*  we clear any timeout*/
if(clearTimer !== null) clearTimeout(clearTimer) 
  try {
/*the callback in setTimeout will be executed regardless of the await keyword below it*/
    clearTimer=setTimeout(checkNetwork, timeout);
    const response = await fetch(url);
    payload = await response.json();
    return payload;
  } catch (error) {
    console.error(error.message);
  }
}

const handleNetwork = () => {
  getPosts();
};

networkBtn.addEventListener("click", handleNetwork);

```


We have assummed that half a second (500ms) is a slow connection for our testing purposes,Open devtools newtork tab `ctrl+shift+I` to throttle network to slow 3G, when you run that code you should see an alert saying _ your internet connection is slow _.

We can cancel the request and ask the user if they wish to retry the request, abort request with `AbortController` then call `getPosts` function again. [Read how to cancel an AJAX request with AbortController](https://dev.to/kipyegonline/cancelling-an-ajax-request-in-javascript-using-the-abort-controller-39o8)

```javascript
const networkBtn = document.getElementById("network-btn");
let timeout = 500; // let assume its too slow at 500ms
let payload = null;
let abortController=null
 let recalled = 0; /* we want to only retry calling the function once to avoid infinite function calls*/

const checkNetwork = () => {
  /* if after half a second payload  variable is still null, 
it means we are still awaiting the promise to settle */
  if (payload === null) {
    if (confirm("Your internet connection is slow, do you wish to retry?")) {
      abortController.abort();
       if (recalled <= 1) getPosts(); 
      recalled++;
    };
  }
};

async function getPosts() {
  abortController = new AbortController();
  let signal = abortController.signal;
  let url = `https://jsonplaceholder.typicode.com/posts/`;
  try {
    setTimeout(checkNetwork, timeout);
    const response = await fetch(url, { signal });
    payload = await response.json();
    return payload;
  } catch (error) {
    console.error(error.message);
  }
}

const handleNetwork = () => {
  getPosts();
};

networkBtn.addEventListener("click", handleNetwork);

```


To summarise, async/await gave javaScript functions a blocking aspect that developers can use to their advantage by pausing everything while they wait for an action to finish while on the other end manipulating with callbacks.


Resources:
[MDN Async function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)
[A Beginner’s Guide to JavaScript async/await, with Examples](
https://www.sitepoint.com/javascript-async-await/)