is JavaScript synchronous, asynchronous or single-threaded

JavaScript is a single-threaded and synchronous language. There are functions that are asynchronous such as fetch.

It is single-threaded which means it doesn’t have any other processes going on at a single time. It is also synchronous which means it can’t move on until something is done.

JavaScript

function hang(seconds) {
    // gets the current time in ms
    const now = new Date().getTime();

    while(new Date().getTime() < now + (seconds * 1000)) {
        /* do nothing */ 
    }
}

The while loop in the hang function makes the page unresponsive because it is taking up the only thread JavaScript has.

This is terrible because if you have a lot of functions that take more then a second to run the page will be really slow and bad.

This problem is the reason that JavaScript has asynchronous functions.

asynchronous JavaScript

Some terms you may have heard of.

execution stack

The execution stack run synchronously and it is whatever JavaScript is running.

If you have a bunch of functions on the stack it pops them off one by one then runs them.

browser APIs

A bunch of functions that is provided by the browser.

window object

If we call one of the browser APIs it is ran separately.

Some browser APIs are setTimeout() and setInterval().

function queue

Queues up functions that are ready to be ran. These functions are pulled from the browser API.

event loop

When the execution stack is cleared it says I need to do something else then the event loop tells the execution stack that there is a function waiting on the function queue then puts one on the stack.

how it works all together

JavaScript

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

After the JavaScript is executed it console logs ‘hello’ after 1 second of waiting.

what happens when it is executed

JavaScript

function printOne() {
    console.log('1');
}

function printTwo() {
    console.log('2');
}

function printThree() {
    console.log('3');
}

setTimeout(printOne, 1000);
setTimeout(printTwo, 0);
printThree();

// 3 2 1

the values console logged are 3 2 1 because setTimeout() is asynchronous.

The first setTimeout() ran is sent to the browser API and waits 1000 seconds.

Then it runs the second setTimeout() which it is sent to the browser API and waits 0 seconds.

printThree() is ran and console logs 3.

After the 0 seconds passes the printTwo() is sent to the function queue then the event loop waits for the execution stack to be empty then sends the printTwo() function from the function queue to the execution stack.

After 1 second passes printOne() is sent to the function queue then the event loop waits for the execution stack to be empty then sends the printOne() function from the function queue to the execution stack.

how to control the flow of asynchronous calls

callbacks can be used to control the flow of asynchronous calls.

JavaScript

function getFruitFromDatabase (callback) {
    setTimeout(function () {
        callback(
            null,
            { name: 'orange', color: 'orange' }
        );
    }, 1000);
}

getFruitFromDatabase((error, fruit) => {
    if (error) return console.error(error);

    console.log(`the fruit name is ${ fruit.name } and the color is ${ fruit.color }.`);
});

promises can also be used.

JavaScript

const getFruitFromDatabase = new Promise((resolve, reject) => {
    setTimeout(function () {
        resolve({ name: 'orange', color: 'orange' });
    }, 1000);
});

getFruitFromDatabase
    .then(fruit => {
        console.log(`the fruit name is ${ fruit.name } and the color is ${ fruit.color }.`);
    })
    .catch(error => {
        console.error(error);
    });

reasons to use promises

conclusion

JavaScript is synchronous and single-threaded with capability to do asynchronous calls.

javascript
first class functions in JavaScript

Functions are first class citizens which mean they are treated like any other variable.

javascript
this in JavaScript

this refers to a object that is set is at the creation of a new execution context.