setTimeout

Running Code Later

Similarly to.addEventListener()code being run at some later point, there is thesetTimeout()function that will run code at a point later in time. ThesetTimeout()function takes:

  • a function to run at some later time
  • the number of milliseconds the code should wait before running the function

Let's check out an example:

setTimeout(function sayHi() {
    console.log('Howdy');
}, 1000);

If we ran this code, the string'Howdy'would appear in the console in about 1,000 milliseconds or in just about 1 second.

SincesetTimeout()is an API provided by the browser, the call tosetTimeout()gives thesayHi()function over to the browser which it starts a timer. After the timer is finished, thesayHi()function moves to the Queue. If the Call Stack is empty, then thesayHi()function is moved to the Call Stack and executed.

setTimeout()with Delay of 0

An interesting aspect tosetTimeout()is that we can pass it a delay of0milliseconds.

setTimeout(function sayHi() {
    console.log('Howdy');
}, 0);  // ← 0 milliseconds!

You might think that since it has a delay of 0 milliseconds, that thesayHifunction would run immediately. However, it still goes through the JavaScript Event Loop. So the function is handed off to the browser where the browser starts a timer for 0 milliseconds. Since the timer ends immediately, thesayHifunction will move to the Queue, and then to the Call Stack once the Call Stack has finished executing any currently-running tasks.

So why is this helpful? Well, this technique can help us to convert potentially long-running code to one that's broken up to allow for the browser to handle user interactions!

Break Up Long-Running Code

Do you remember back to a previous section when we wrote JavaScript code to add two hundred paragraphs to the page? Now, instead of adding twohundred_paragraphs to the page, what if we added_twenty thousand? That's a lot of elements to create, append, and insert into the page!

Now keep in mind how reflow and repaint affect an app's performance. We want to write our JavaScript code to take into consideration reflow and repaint and to cause the fewest number of these.

However, we also want to make sure our app is responsive to user interaction. While JavaScript is running, the page is "busy" and the user won't be able to interact with the page (e.g. clicking a button, filling out a form). Remember that this is because JavaScript runssynchronously. So it will run to completion (creating, appending, and inserting all twenty thousand elements), and it does this_before_it is able to respond to any actions the user has taken. The function creates all of these elements and adds the to the page will be in the Call Stack until it's completely finished.

One way to give the user a chance to interact with the page is to break up the adding of the content into chunks. Let's do this withsetTimeout():

let
 count = 
1
function
generateParagraphs
(
) 
{

const
 fragment = 
document
.createDocumentFragment();


for
 (
let
 i = 
1
; i 
<
= 
500
; i++) {

const
 newElement = 
document
.createElement(
'p'
);
        newElement.textContent = 
'This is paragraph number '
 + count;
        count = count + 
1
;

        fragment.appendChild(newElement);
    }


document
.body.appendChild(fragment);


if
 (count 
<
20000
) {
        setTimeout(generateParagraphs, 
0
);
    }
}

generateParagraphs();

This code starts off by setting acountvariable to1. This will keep track of the number of paragraphs that have been added. ThegenerateParagraphs()function will add 500 paragraphs to the page each time it's invoked. The interesting thing is that there's asetTimeout()call at the end of thegenerateParagraphs()function. If there less than twenty thousand elements, then itsetTimeout()will be used to call thegenerateParagraphs()function.

If you try running this code on a page, you can still interact with the page while the code is running. It doesn't lock up or freeze the page. And it doesn't lock up or freeze because of thesetTimeout()calls.

setTimeout()Recap

The browser-providedsetTimeout()function takes another function and a delay, and invokes the function after the delay has passed.

Knowing how the JavaScript Event Loop works, we can use thesetTimeout()method to help us write code that allows the browser to handle user interactions.

Further Research

results matching ""

    No results matching ""