Asynchronous JavaScript 🔥

 Laying foundations to Promises

Big Bang...

13.8 billion years ago, universe expanded from a singularity giving birth to galaxies, stars, planets, life and TIME!

 

Now JavaScript and Browsers need to deal with this relic.

Photo by Jeremy Thomas on Unsplash

Order


console.log("print first");
setTimeout(secondPrint,0); // 0 DELAY
setTimeout(thirdPrint,10); 
console.log("print fourth");

function secondPrint(){
    console.log("print second");
}

function thirdPrint(){
    console.log("print third");
}

// print first
// print second
// print third
// print fourth
// print first
// print fourth
// print second
// print third
// print first
// print second
// print fourth
// print third
A.
B.
C.

Let's slow time down...🐌

Run To Completion🏃





Console

Stack

Heap

Queue

console.log("print first");
setTimeout(secondPrint,0);
setTimeout(thirdPrint,10);
console.log("print fourth");

Run To Completion🏃



console.log("print first");


setTimeout(secondPrint,0);
setTimeout(thirdPrint,10);
console.log("print fourth");
Console

Stack (Main Thread)

Heap

Queue

Run To Completion🏃


"print first"

setTimeout(secondPrint,0);



setTimeout(thirdPrint,10);
console.log("print fourth");
Console

Stack (Main Thread)

Heap

Queue

Run To Completion🏃


"print first"

setTimeout(thirdPrint,10);

setTimeout(secondPrint,0);



console.log("print fourth");
Console

Stack (Main Thread)

Heap

Queue

Run To Completion🏃


"print first"


setTimeout(thirdPrint,10);



console.log("print fourth");
secondPrint
Console

Stack (Main Thread)

Heap

Queue

Run To Completion🏃


"print first"

console.log("print fourth");

setTimeout(thirdPrint,10);




secondPrint
Console

Stack (Main Thread)

Heap

Queue

Run To Completion🏃


"print first"
"print fourth"

secondPrint
<empty>




thirdPrint
Console

Stack (Main Thread)

Heap

Queue

Run To Completion🏃


"print first"
"print fourth"
"print second"

thirdPrint
<empty>
<empty>
Console

Stack (Main Thread)

Heap

Queue

Run To Completion🏃


"print first"
"print fourth"
"print second"
"print third"

<empty>
<empty>
<empty>
Console

Stack (Main Thread)

Heap

Queue

Order


console.log("print first");
setTimeout(secondPrint,0); // 0 DELAY
setTimeout(thirdPrint,10); 
console.log("print fourth");

function secondPrint(){
    console.log("print second");
}

function thirdPrint(){
    console.log("print third");
}
// print first
// print fourth
// print second
// print third
B.

Run To Completion

  • All lines within a function are executed until the end (run-to-completion)
  • No other thread can interrupt the JS execution flow (single threaded & blocking)
  • The browser can do multi-tasking via Web APIs such as events and AJAX (non-blocking)
  • setTimeout honors minimum wait time, doesn't guarantee immediate execution after timeout.

Find the boss....

  • Stack takes orders from Queue
  • Queue takes orders from the Heap
  • Heap takes orders from the Stack

➿ Event Loop 🔥

while(browser.alive){
    if(stack.empty && !queue.empty){
        stack.push(queue.next)
    }
}

Browser Internal...

@MDN

Callback Heaven 😇

let coordinates;
navigator
  .geolocation
  .getCurrentPosition((position)=>{
    coordinates=position;
});
console.log(coordinates);

Callback Heaven Detached

let coordinates;
//navigator
//  .geolocation
//  .getCurrentPosition((position)=>{
//    coordinates=position;
//});
console.log(coordinates);

Callback Hell 😱

.getCurrentPosition((position)=>{
   getWeather(position,(weather)=>{
      getIcon(status,(success)=>{
          //display weather
      },handleIconError);
   },handleWeatherError)
},handlePositionError);

Inversion of Control 🙅

$.ajax({
    url: apiURL,
    success: data=>{
      //valid data from HTTP
      console.log('success',data);
    },
    error: (xhr,status)=>{
      //HTTP or parsing error
      console.log('error',status);
    }
});

Be in Control 👌

fetch(apiURL)
  .then(validate)
  .then(data => console.log('success',data))
  .catch(error => console.log('error',error));

Unleashing Promises

getCoordinates
.then(getWeather)
.then(getIcon)
.then(displayResult)
.catch(handleError);

Producing Promises

const p = new Promise((resolve, reject) => {
  //asynchronous activity
  //call resolve when things go ok
  //call reject on error
});

Consuming Promises

promise
.then(resolveFunction)
.catch(rejectFunction);

function resolveFunction(data) {
  //process data
}

function rejectFunction(error) {
  // handle error 
}

Promise.resolve 🗸

Create an already resolved promise

let p1=Promise.resolve(2);
let p2=Promise.resolve(p1);

p1.then(console.log);//2
p2.then(console.log); //2 !!

Promise.reject 🗴

Create an already rejected promise

let p1=Promise.reject(2);
let p2=Promise.resolve(p1);

p1.then(x=>x*x)
  .catch(e=>console.log("Err:", e));
  //Err:2

p2.then(x=>x*x)
  .catch(e=>console.log("Err:", e));
  //Err:2

😴

🎇 Features & Options 🎆

 

 

No Rush, State is Retained 👌

let data=fetch(url); // network request
//do
//hundred
//other 
//things
data.then(worksOK);

Immutable 👌

let p1=Promise.resolve(2);

p1.then(x=>x*x)
  .then(console.log); //4

p1.then(console.log); //2 !!

Immutable - Gotcha! 😓

let result=fetch(url);
result
  .then(res => res.json())
  .then(console.log);

//oh, I want to reuse that result again

result
  .then(res=>res.json())
  .then(processJSON);
  //TypeError; body stream already read

Fix : Immutable - Gotcha!😅

let result=fetch(url);
result
  .then(response=>response.clone())
  .then(res => res.json())
  .then(console.log);

//oh, I want to reuse that result again
result
  .then(res=>res.json())
  .then(processJSON);

Cool Error Handling 👌

promise
.then(process,initialErrors)
.then(transform)
.catch(handle)
.then(display)
.catch(inform);

Auto-wrap into Promise

let promise=Promise.resolve(2);

promise
.then(x=>x*x)
.then(console.log);//4

Thenable

let p1=Promise.resolve(2);

p1
  .then(x=>x*x)           // 4
  .then(x=>[x**x])        // [256]
  .then(x=>x.toString())  // 256
  .then(x=>x.split(''))   // ["2","5","6"]
  .then(console.log);     // ["2","5","6"]

Thenable - Gotcha!😓

let promise=Promise.resolve(2);

promise
.then(x=>x*x)
.then(console.log) //4
.then(console.log); //undefined!

Fix: Always Return a Value😅

let promise=Promise.resolve(2);

promise
.then(x=>x*x)
.then(x=>{
  console.log(x);
  return x; //✌
) //4
.then(console.log); //4!

Finally...

let p=Promise.resolve(2);
p.then(callback1)
 .catch(errorHandler1)
 .finally(()=>{
    // clean up
    // inform
    //wind up
 });

//⚠: BROWSER SUPPORT

Promise.race

  • Promise.race(first,successful,one,is,enough)

Promise.all

  • Promise.all(each,one,is,necessary)

Microtasks

let p=Promise.resolve("promise");

setTimeout(console.log,0,"timeout");
p.then(console.log); 
console.log("insider");

// insider
// promise 🔥
// timeout

Async/Await

async function fun(){
    await Promise.resolve(1);
    console.log("fun");
}
function syncTest(){
    fun();
    console.log("after");
}

syncTest();
//after
//fun
async function asyncTest(){
    await fun();
    console.log("after");
}

asyncTest();
//fun
//after

Browser Support 🔥

Above and Beyond

Thank You

🙏

Made with Slides.com