The Call Stack

Single Threading

You might've heard that JavaScript issingle-threadedbut what does that mean? According to Wikipedia, single-threading is:

the processing of one command at a time (source)

Ok, so JavaScript can "process" one command at a time. The opposite of single-threading, is multithreading. There are numerous pros and cons to both which we won't be getting into (feel free to check out theWikipedia article on Threading#Single_threading) for more info about the pros and cons). We're going to take a look at JavaScript's single-threaded model and how/why we should write our code to take advantage of it.

Let's look at some code:

function addParagraph() {
    const para = document.createElement('p');
    para.textContent = 'JavaScript is single threaded!';
    document.body.appendChild(para);
}

function appendNewMessage() {
    const para = document.createElement('p');
    para.textContent = "Isn't that cool?";
    document.body.appendChild(para);
}

addParagraph();
appendNewMessage();

Keeping JavaScript's single-threaded nature in mind (meaning it can only perform one task at a time), let's break down this code into the order it will run:

  • the addParagraph()function is declared on line 1
  • the appendNewMessage() function is declared on line 6
  • addParagraph() is called on line 13
    • execution moves into the function and executes all three lines in order
    • now that the function is finished, execution returns to where it was called
  • the appendNewMessage() function is called on line 14
    • execution moves into the function and executes all three lines in order
    • now that the function is finished, execution returns to where it was called
  • the program ends because all lines of code have been executed

Hopefully, the order that this code executed in wasn't surprising. There are a couple of things I particularly want you to pay attention to. First, is the run-to-completion nature of the code. WhenaddParagraph()is invoked on line 13,all of the code in the function gets executed: it doesn't just execute some lines and leave other lines to be executed later. The entire block of code is run. A second thing I want to point out is thataddParagraph()is invoked, runs, and finishesbeforeappendNewMessage()is invoked (including a possible reflow and repaint); JavaScript doesn't execute multiple lines/functions at the same time (this is single-threading...processing one command at a time!).

I have a question for you - onceaddParagraph()has been invoked and it runs the lines of code inside theaddParagraph()function, how does it know to goback toappendNewMessage()? How does it keep track of that?

What if we changed this code slightly to create nested functions:

function addParagraph() {
    const para = document.createElement('p');
    para.textContent = 'JavaScript is single threaded!';

    appendNewMessage();
    document.body.appendChild(para);
}

function appendNewMessage() {
    const para = document.createElement('p');

    para.textContent = "Isn't that cool?";
    document.body.appendChild(para);
}

addParagraph();

Notice that the call toappendNewMessage()is locatedinside theaddParagraph()function. First,addParagraph()is invoked. ThenappendNewMessage()is invoked on line 5. OnceappendNewMessage()has finished running, execution returns and finishes running the last line of code in theaddParagraph()function...but how does it know how to do that? How does the JavaScript engine know where it left off and how to get back to it?

The Call Stack

The JavaScript engine keeps a call stack (basically a list) of the functions that are running. When a function is invoked, it is added to the list. When all of the code inside a function has been run, then the function is removed from the call stack. The cool part about a call stack is that a function doesn't have to complete before another function is added to the call stack.

Let's see how this works!

QUESTION 1 OF 2

How many items (frames) will be on the stack when the code reaches the"stop here"comment?

function quiz () {
  var y = 'yes';
  questions();
  fun();
}
function questions () {
  var y = 'no';
  return 7;
}
function are () {
  return 3;
}
function fun () {
  are();
  // stop here
}

quiz()

Assume there is no "<main>"/default frame.

  • 0

  • 1

  • 2

  • 3

  • 4

SUBMIT

Use this code for the following question.

function dolphins () {
  // stop here
  return 'llamas';
}
function rhinos () {
  var y = 'no';
  return penguins();
}
function penguins () {
  return camels();
}
function camels () {
  return dolphins();
}

rhinos()

QUESTION 2 OF 2

Put the function names in the correct order they would appear when the// stop herecomment is reached. Remember to put the oldest/initial at the bottom of the stack. Assume there is no "<main>"/default frame.

camels

dolphins

rhinos

penguins

ORDER OF STACK

FUNCTION NAME

Top of the stack

2nd item in the stack

3rd item in the stack

bottom of the stack

SUBMIT

The Call Stack Recap

In this section, we looked at how JavaScript is a single-threaded programming language, which means it can only execute one thing at a time. We looked at how JavaScript keeps track of what functions are running by using the Call Stack.

Further Research

results matching ""

    No results matching ""