Promises & Async 

Promises

This lets asynchronous methods return values like synchronous methods: instead of immediately returning the final value, the asynchronous method returns a promise to supply the value at some point in the future.

Source: MDN Web Docs

A Promise is a proxy for a value not necessarily known when the promise is created. It allows you to associate handlers with an asynchronous action's eventual success value or failure reason.

 

Child: I want a cookie

Dad: You will get a cookie after I check your room

Dad: If its clean you will receive a cookie

Dad: If its dirty, no cookie for you

Dad: I checked your room, its clean, here is your cookie

Child: Thanks, I`m eating the cookie now

data

promise

resolved

rejected

resolved

data

Promises

History

Promises were proposed as a spec back in 2012.

And became part of ECMAScript standard in es6 ( es2015 )

Promises have been used in form or another in some libraries like:

  • Q
  • when
  • WinJS
  • RSVP.js
  • Bluebird

In jQuery they were called Deferreds

fulfilled

settled

rejected

pending

Promise

Syntax

const promise = new Promise( ( resolve, reject ) => {
    const condition = true; // you should add a better condition
    if ( condition ) {
        resolve( "Success" );    
    } else {
        reject( "error" );
    }
} );

.then

const promise = new Promise( ( resolve, reject ) => {
    const condition = false; // you should add a better condition
    if ( condition ) {
        resolve( "Success" );    
    } else {
        reject( "Error" );
    }
} );


promise.then( 
    data => console.log( "Resolved: ", data ),
    data => console.log( "Rejected: ", data )
);

// this will write in the console: Rejected: Error

then and catch

const promise = new Promise( ( resolve, reject ) => {
    const condition = true; // you should add a better condition
    if ( condition ) {
        resolve( "Success" );    
    } else {
        reject( "error" );
    }
} );

// Option 1:
promise.then( data => console.log( "Resolved: ", data ) )
       .catch( data => console.log( "Rejected", data ) );

// this will write in the console: Fulfilled: Success

then vs catch

const promise = new Promise( 
   ( resolve, reject ) => setTimeout( ( ) => resolve(3), 2000 )
);

promise
    .then( () => console.log( "then" ) )
    .catch( () => console.log( "catch" ) )


promise
    .then( 
        () => console.log( "then" ), 
        () => console.log( "catch" )
    );

then vs catch

const promise = new Promise( 
    ( resolve, reject ) => setTimeout( ( ) => resolve(3), 2000 )
);

promise
    .then( 
        () =>  {
        console.log( "then " );
        throw "Some error";
        } 
    )
    .catch( ( err ) => console.log( "catch", err ) )


promise
    .then( 
        () =>  {
        console.log( "then " );
        throw "Some error";
        },
        () => console.log( "inside Catch" )
    );
new Promise( ( resolve, reject ) => {
   setTimeout(() => resolve(1), 2000);
})
.then( ( data ) => {
  console.log("First Then ", data );
  return data + 1;
} )
.then(  ( data ) => {
  console.log("Second Then ", data );
  return data + 1;
} );

Promise chaining

const prom = new Promise( ( resolve, reject ) => { 
    setTimeout( ( ) => resolve(3), 3000 );
} )

prom
    .then( ( data ) => console.log( "First Then", data) )
    .then( ( data ) => {
        console.log( "Second Then ", data );
        return Promise.reject( "reject" );
    } )
    .then( ( success ) => console.log ("Third Then ", success ) )
    .catch( ( error ) => console.log( "Catch ", error ) )

Promise chaining

First Then Data 3

Second Then undefined

Catch reject

const promiseArray = [
  new Promise((resolve, reject) => setTimeout(() => resolve(1), 3000)), // 1
  new Promise((resolve, reject) => setTimeout(() => resolve(2), 2000)), // 2
  new Promise((resolve, reject) => setTimeout(() => resolve(3), 1000))  // 3
];

Promise.all(promiseArray).then( data => console.log( data ) ); // [ 1, 2, 3 ] 

Promise All

In case one of the promises fails, the promise all will be rejected.

Promise All

Only the value returned by the first rejected promise can be caught as a rejection, the rest will be ignored

const promiseArray = [
  new Promise((resolve, reject) => setTimeout(() => resolve(1), 1000)), // 1
  new Promise((resolve, reject) => setTimeout(() => reject(2), 3000)), // 2
  new Promise((resolve, reject) => setTimeout(() => reject(3), 1000))  // 3
];

Promise.all(promiseArray).then( 
( data ) => console.log( data ),
( err ) => console.log( err ) ); // 3
Promise.race([
  new Promise((resolve, reject) => setTimeout(() => resolve(1), 3000)), // 1
  new Promise((resolve, reject) => setTimeout(() => resolve(2), 2000)), // 2
  new Promise((resolve, reject) => setTimeout(() => resolve(3), 1000))  // 3
])
.then( ( data ) => console.log( data ) ); //logs out 3

Promise Race

Only first promise that gets settled( fulfilled or rejected ) is taken in consideration

new Promise( ( resolve, reject ) => {
   setTimeout(() => resolve(1), 2000);
})
     .then( ( data ) => {
      console.log("First Then ", data ); // First Then 1
      return data + 1;
    } )
    .then(  ( data ) => {
      console.log("Second Then ", data ); // Second Then 2
      return data + 1;
    } )
    .finally( ( ) => console.log( "I`m finally done" ) )

Promise Finally

The finally() method returns a Promise. When the promise is settled, whether fulfilled or rejected, the specified callback function is executed. This provides a way for code that must be executed once the Promise has been dealt with to be run whether the promise was fulfilled successfully or rejected.

Async / Await

Async functions  allow you to write promise-based code as if it were synchronous, but without blocking the main thread. They make your asynchronous code less "clever" and more readable.

History

Async / Await was introduced in ES2017 ( es8 )

Async / Wait was proposed as a spec back in 2014.

It became fully supported in node 8

Syntax

const resolveAfter2Seconds = () => new Promise( resolve => {
    setTimeout(() => {
      console.log("resolving");
      resolve("resolved");
    }, 2000);
});

async function asyncCall() {
  console.log("calling");
  const result = await resolveAfter2Seconds();
  console.log(result); // "resolved"
}

asyncCall();

Multiple awaits

const resolveAfter2Seconds = () => new Promise( resolve => {
    setTimeout(() => {
      console.log("resolving");
      resolve("resolved");
    }, 2000);
});

async function asyncCall() {
  console.log("calling");
  const result = await resolveAfter2Seconds();
  const secondResult = await resolveAfter2Seconds();
  console.log(result); // "resolved"
  console.log(secondResult); // "resolved"
}

asyncCall();

Async / Await error handling

const rejectAfter2Seconds = () => new Promise( ( resolve, reject ) => {
    setTimeout(() => {
      reject("rejected");
    }, 2000);
 });

async function asyncCall() {
  console.log("calling");
  try {
      const result = await rejectAfter2Seconds();
      console.log( "result ", result );
  } catch ( e ) {
      console.log( "There was an error ", e ); //
  }
}

asyncCall();

Async / wait error handling

const resolveAfter2Seconds = () => new Promise( resolve => {
    setTimeout(() => {
      console.log("resolving");
      resolve("resolved");
    }, 2000);
 });

const rejectAfter2Seconds = () => new Promise( ( resolve, reject ) => {
    setTimeout(() => {
      console.log("rejecting");
      reject("rejected");
    }, 2000);
 });

async function asyncCall() {
  console.log("calling");
  try {
      const result = await resolveAfter2Seconds();
      const secondResult = await rejectAfter2Seconds();
      console.log(result); // "resolved"
      console.log(secondResult); // "rejected"
  } catch ( e ) {
      console.log( "There was an error ", e ); //
  }
}

asyncCall();
Made with Slides.com