JavaScript the Fun Part


modern-javascript

why-promises


Explanation about promises are a lot. Mastering them in a single approach is not possible. So here we first see what kind of problems we have, and then we look at how it works.

Event Driven Architecture

If you ever worked with a browser, coding some JS, then you have experienced

even if you have gone deep to the JS ecosystem then you are familiar with

All of these are related to Event Driven Architecture or EDA for short.

And yes, you guessed it, Web Browsers that we use for surfing the web are based on this architecture.

Asynchronous nature of user interaction with a browser forces them (= browsers) to have this model at their core.

Since JS is the heart of DOM manipulation; it has to deal with these events all the time.

Result? JS has to handle asynchronous events and manage them all the time.

Exception Handling

There is no system with no error and we have to take care about errors not just for catching them, but for catching them as soon as they occur.

Is it possible to catch an exception when actions are based on asynchronous stuff? No.

One drawback of Event Driven Architecture is the hardiness of exception handling because events happen in background, they happen when we are doing something else and therefore occurring an error can be easily overlooked.

And when we have many asynchronous events then managing their exceptions become harder and harder.

Asynchronous Synchronization

Happening at any time later and not be able to rely on an event causes us to easily lose needed data.

Here is an example that we assign a string to a variable asynchronously.

const log = console.log.bind( console );

log( "--- start ---" );

let name = "";

// asynchronous stuff
// it happens later as a macro Task
// after call stack is empty
setTimeout(function rename(){
    name = "JS";
}, 0 );

// name is empty at this point
log( "name is:", name ); // has not been set!!!

log( "---- end ----" );

output

--- start ---
name is: 
---- end ----

This was just one example. What if we have 100 of them in our program? What is the solution?

Solution: using functions recursively so they happen after each other..

When we have asynchronous operations, for synchronizing them we have add them inside each other. In above case we has to print it inside that function.

const log = console.log.bind( console );

log( "--- start ---" );

let name = "";

// asynchronous stuff
// it happens later as a macro Task
// after call stack is empty
setTimeout(function rename(){
    name = "JS";
    log( "inside rename functin:", name );
}, 0 );

// name is empty at this point
log( "name is:", name ); // has not been set!!!

log( "---- end ----" );

output

--- start ---
name is: 
---- end ----
inside rename functin: JS

So if we had 100 asynchronous rename function we had to use them inside each other like so

const log = console.log.bind( console );

log( "--- start ---" );

const o1 = {
    word: ""
}

const o2 = {
    word: ""
}

const o3 = {
    word: ""
}

function setWord( input, value ){
    input.word = value
}


// asynchronous stuff
// it happens later as a macro Task
// after call stack is empty
setTimeout(function(){
    setWord( o1, "JS" );
    setTimeout(function(){
        setWord( o2, " is " );
        setTimeout(function(){
            setWord( o3, "great!" );
            const sentence = o1.word + o2.word + o3.word;
            log( "sentence:", sentence );
        }, 0 );
    }, 0 );
}, 0 );

const sentence = o1.word + o2.word + o3.word;
log( "sentence:", sentence );

log( "---- end ----" );

output

--- start ---
sentence: 
---- end ----
sentence: JS is great!

Callback Hell or Pyramid of doom

There is a pattern if look at it carefully. An much as we have more asynchronous operation, we have more nested functions, so a V style shape.

It has an actual name called Pyramid of doom.

This is also a drawback of synchronizing asynchronous operations.

setTimeout(function(){
    setWord( o1, "JS" );
    setTimeout(function(){
        setWord( o2, " is " );
        setTimeout(function(){
            setWord( o3, "great!" );
            const sentence = o1.word + o2.word + o3.word;
            log( "sentence:", sentence );
        }, 0 );
    }, 0 );
}, 0 );

Solution?

In ES6 we have a function constructor which as its names implies it is called Promise.

It has been got through JS language for solving the problems we saw here. Lets go to next part to see what it is.

some resources


Update: Sat Sep 28 2019 17:38:29 GMT+0330 (Iran Standard Time)