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();
Promises & Async
By Daniel Mocan
Promises & Async
- 195