Loop with delay javascript

Delay, Sleep, Pause, & Wait in JavaScript

Many programming languages have a sleep function that will delay a program’s execution for a given number of seconds. However, this functionality is absent from JavaScript due to its asynchronous nature. In this article, we’ll look briefly at why this might be, then how we can implement a sleep function ourselves.

Understanding JavaScript’s Execution Model

Before we get going, it’s important to make sure we understand JavaScript’s execution model correctly.

Consider the following Ruby code:

require 'net/http' require 'json' url = 'https://api.github.com/users/jameshibbard' uri = URI(url) response = JSON.parse(Net::HTTP.get(uri)) puts response['public_repos'] puts "Hello!" 

As one might expect, this code makes a request to the GitHub API to fetch my user data. It then parses the response, outputs the number of public repos attributed to my GitHub account and finally prints “Hello!” to the screen. Execution goes from top to bottom.

Contrast that with the equivalent JavaScript version:

fetch('https://api.github.com/users/jameshibbard') .then(res => res.json()) .then(json => console.log(json.public_repos)); console.log("Hello!"); 

If you run this code, it will output “Hello!” to the screen, then the number of public repos attributed to my GitHub account.

This is because fetching data from an API is an asynchronous operation in JavaScript. The JavaScript interpreter will encounter the fetch command and dispatch the request. It will not, however, wait for the request to complete. Rather, it will continue on its way, output “Hello!” to the console, then when the request returns a couple of hundred milliseconds later, it will output the number of repos.

If any of this is news to you, you should watch this excellent conference talk: What the heck is the event loop anyway?.

You Might Not Actually Need a JS Sleep Function

Now that we have a better understanding of JavaScript’s execution model, let’s have a look at how JavaScript handles delays and asynchronous operations.

Create a Simple Delay Using setTimeout

The standard way of creating a delay in JavaScript is to use its setTimeout method. For example:

console.log("Hello"); setTimeout(() =>  console.log("World!"); >, 5000); 

This would log “Hello” to the console, then make JavaScript wait 5 seconds, then log “World!” to the console. And in many cases, this is enough: do something, wait, then do something else. Sorted!

However, please be aware that setTimeout is an asynchronous method. Try altering the previous code like so:

console.log("Hello"); setTimeout(() =>  console.log("World!"); >, 5000); console.log("Goodbye!"); 

Waiting for Things with setTimeout

It’s also possible to use setTimeout (or its cousin setInterval ) to make JavaScript or TypeScript wait until a condition is met. For example, here’s how you might use setTimeout to wait for a certain element to appear on a web page:

function pollDOM ()  const el = document.querySelector('my-element'); if (el.length)  // Do something with el > else  setTimeout(pollDOM, 300); // try again in 300 milliseconds > > pollDOM(); 

This assumes the element will turn up at some point. If you’re not sure that’s the case, you’ll need to look at canceling the timer (using clearTimeout or clearInterval ).

If you’d like to find out more about JavaScript’s setTimeout method, please consult our tutorial which has plenty of examples to get you going.

Flow Control in Modern JavaScript

When writing JavaScript, we often need to make JS wait for something to happen (for example, data to be fetched from an API), then do something in response (such as update the UI to display the data).

The example above uses an anonymous callback function for this purpose, but if you need to wait for multiple things to happen, the syntax quickly gets pretty gnarly and you end up in callback hell.

Luckily, the language has evolved considerably over the past few years and now offers us new constructs to avoid this.

For example, using async await we can rewrite the initial code to fetch information from the GitHub API:

(async () =>  const res = await fetch(`https://api.github.com/users/jameshibbard`); const json = await res.json(); console.log(json.public_repos); console.log("Hello!"); >)(); 

Now the code executes from top to bottom. The JavaScript interpreter waits for the network request to complete and the number of public repos is logged first, then the “Hello!” message.

If this is more the sort of thing you’re trying to accomplish, I encourage you to read our article Flow Control in Modern JS: Callbacks to Promises to Async/Await.

Bringing Sleep to Native JavaScript

If you’re still with me, then I guess you’re pretty set on blocking that execution thread and making JavaScript wait it out.

Here’s how you might do that:

function sleep(milliseconds)  const date = Date.now(); let currentDate = null; do  currentDate = Date.now(); > while (currentDate - date  milliseconds); > console.log("Hello"); sleep(2000); console.log("World!"); 

As expected, this will log “Hello”, pause for two seconds, then log “World!”

It works by using the Date.now method to get the number of milliseconds that have elapsed since January 1, 1970 and assigning that value to a date variable. It then creates an empty currentDate variable, before entering a do . while loop. In the loop it repeatedly gets the number of milliseconds which have elapsed since January 1, 1970 and assigns the value to the previously declared currentDate variable. The loop will keep going while the difference between date and currentDate is less than the desired JS delay in milliseconds.

Job done, right? Well not quite …

A Better Sleep Function

Maybe this code does exactly what you’re hoping for, but be aware, it has a large disadvantage: the loop will block JavaScript’s execution thread and ensure that nobody can interact with your program until it finishes. If you need a large delay, there’s a chance that it may even crash things altogether.

Well, it’s also possible to combine the techniques learned earlier in the article to make a less intrusive sleep function:

function sleep(ms)  return new Promise(resolve => setTimeout(resolve, ms)); > console.log("Hello"); sleep(2000).then(() =>  console.log("World!"); >); 

This code will log “Hello”, wait for two seconds, then log “World!” Under the hood we’re using the setTimeout method to resolve a Promise after a given number of milliseconds.

Notice that we need to use a then callback to make sure the second message is logged with a delay. We can also chain more callbacks onto the first:

console.log('Hello') sleep(2000) .then(() => console.log('world!')) .then(() => sleep(2000)) .then(() => console.log('Goodbye!')) 

This works, but I’m not the biggest fan of all the .then() s. We can pretty it up using async . await :

function sleep(ms)  return new Promise(resolve => setTimeout(resolve, ms)); > async function delayedGreeting()  console.log("Hello"); await sleep(2000); console.log("World!"); await sleep(2000); console.log("Goodbye!"); > delayedGreeting(); 

This looks nicer, but means that whatever code is using the sleep function needs to be marked as async .

Of course, both of these methods still have the disadvantage (or feature) that they do not pause the entire program execution. Only your function sleeps:

function sleep(ms)  return new Promise(resolve => setTimeout(resolve, ms)); > async function delayedGreeting()  console.log("Hello"); await sleep(2000); console.log("World!"); > delayedGreeting(); console.log("Goodbye!"); 

The code above logs the following:

Conclusion

Timing issues in JavaScript are the cause of many a developer headache, and how you deal with them depends on what you’re trying to achieve.

Although a sleep function is present in many other languages, I’d encourage you to embrace JavaScript’s asynchronous nature and try not to fight the language.

If you’d like to develop a deeper understanding of JavaScript, then check out our Free Book: Learn to Code with JavaScript. This comprehensive guide covers the language from the ground up (including working with asynchronous code) using the latest JS syntax.

Or, if you have any questions, please head over to the SitePoint forums and start a discussion.

Share This Article

Network admin, freelance web developer and editor at SitePoint.

Источник

How to Add a Delay in a JavaScript Loop

It’s easy to add delays in for loops when using versions of JavaScript that support async / await .

One common reason to sleep in JavaScript is to throttle the requests made to websites when Web scraping.

Here’s some example JavaScript code that will create a delay:

const sleep = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)); 

You can use that function in an async function and await the sleep timer.

Full Example of a Sleep Timer in Node.js

Here’s a working example for Node.js. It will scrape some JSON data from a couple of APIs and save the data to a file. There will be a 4-second delay between each request made in the for loop.

If you’re using a version of Node.js that is older than 17.5, you’ll need to install node-fetch .

For example, run npm i node-fetch or yarn add node-fetch .

(At the time of writing this post, I am using Node 16.)

Put the code below into a file named scraper.mjs , read through it, and then run it with node scraper.mjs .

// This line is only needed if you are using a version of Node.js that is older // than 17.5. import fetch from "node-fetch"; import fs from "fs"; // Here's the sleep timer. const sleep = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)); async function fetchData(urls) < // For the purpose of the example, we'll sleep for 4 seconds to clearly show // that it's working. const delay = 4000; const output = []; for (let i = 0; i < urls.length; i++) < console.log("fetching", urls[i]); // await the response and extract the JSON data as a JavaScript object. const response = await fetch(urls[i]); const data = await response.json(); // Push the data into the output array. output.push(data); // This displays the data to show that the delay is really working. console.log("got this data:", data); // Await the sleep timer before going back to the beginning of the loop. console.log(`sleeping for $ms`); await sleep(delay); > return output; > function writeDataToFile(data) < // This creates a filename with a timestamp in it to avoid overwriting files // from previous runs of the scraper. const filename = Date.now() + "-data.json"; const formattedJSON = JSON.stringify(data, null, 4); fs.writeFileSync(filename, formattedJSON); console.log("wrote file", filename); >async function main() < // Any URL that returns JSON will work here. const urls = [ "https://api.github.com/", "https://api.coinbase.com/v2/currencies", ]; const data = await fetchData(urls); console.log(`You scraped data from $URLs`); // Do whatever you want with the data here. // In this case it saves it to a file. writeDataToFile(data); > // Run the scraper. main(); 

If you have suggestions, tips, or questions, leave a comment below.

Feedback and Comments

What did you think about this article? Do you have any questions, or is there anything that could be improved? You can leave a comment after clicking on an icon below.

Источник

How to add a delay in a JS loop

Many candidates are rejected or down-leveled in technical interviews due to poor performance in behavioral or cultural fit interviews. Ace your interviews with this free course, where you will practice confidently tackling behavioral interview questions.

JavaScript (JS) loops perform iterations through your code until a certain condition is met. The while , for , and do while loops are used to execute the condition. Depending on the task being executed, you might need to add a delay to the loop. This becomes possible by adding the setTimeout() method in JavaScript.

In this Answer, we will cover how to add a delay in a JS loop after every iteration and how to add an instant delay only at the start of the loop.

Let’s use the setTimeout() method to add a 3 seconds delay in a while loop:

Example 1

let i = 0;
while (i<5)
loop(i);
i++
>
function loop(i)
setTimeout(function()
console.log(i);
>, 3000 * i)
>

In the above code, we execute a loop that iterates from 0–4. However, the function below the loop calls the setTimeout() method to execute our variable after a 3 seconds delay on every iteration.

Below is an example of a 4 seconds delay added to a for loop:

Example 2

for (let people = 8; people
project(people)
>
function project(people)
setTimeout(function()
console.log(people);
>, 4000 * people );
>

The same concept will also be applied in a do while loop as shown below:

Example 3

let i = 3;
do
loop(i);
i++;
> while (i < 6);
function loop(i)
setTimeout(function()
console.log(i);
>, 4000 * i);
>

In the above code, the loop will always iterate to the next number after every 4 seconds as an output of the setTimeout() method.

How to add an instant delay only at the start of the loop

Adding an instant delay at the start of every loop will only require a time stamp without multiplying our variable with the milliseconds.

An example of an instant delay with the for loop is shown below:

Источник

Читайте также:  Html select option href
Оцените статью