0% found this document useful (0 votes)
20 views19 pages

Promises and Async

Uploaded by

ercole
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
20 views19 pages

Promises and Async

Uploaded by

ercole
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 19

Course Schedule • Synchronous Code

• Asynchronous Code
• Handling Callbacks
• Promises and Async • Callback Hell
• Promises
• Promise Chaining
• Infinite Chaining
• Creating Promises
• Resolving Promises
• Catching Errors
• Parallel Execution
• Promise States
• Consuming Promises
• Promises Guarantees
• Promises are Asynchronous
• Async Await

www.spiraltrain.nl 1
Synchronous Code

• JavaScript is synchronous by default and is single threaded :


• Each statement is executed one after the other
• Code cannot create new threads and run in parallel
function syncTask1(i){
return i + 1;
}
function syncTask2(i){
return i + 1;
}
function syncTask3(i){
return i + 1;
}
x = syncTask1(0);
y = syncTask2(x);
z = syncTask3(y)

• Sometimes need to execute code only after occurrence of event :


• When someone clicks a button Demo01
Synchronous Code
• When the database finally responds to query
www.spiraltrain.nl Promises and Async 2
Asynchronous Code

• Asynchronous code is code executed when something happens :


• Cannot always wait for events to complete because it takes time
• Time that we can otherwise use to execute some other code
• Different ways in JavaScript to create asynchronous code :
• Callbacks
• Promises
• Async/Await
• RxJS Observables
• Callbacks are classical approach to asynchronous programming :
• Provide function as argument to another function that executes an asynchronous task
• Promises where introduced in ECMAScript 2015 :
• Allow for more readable asynchronous code than is possible with callbacks
• Async/await has been introduced in ECMAScript 2017 :
• Is just syntactic sugar for working with promises Demo02
Asynchronous Callbacks
• RxJS Observables are not part of JavaScript :
• Provided by external RxJS library
www.spiraltrain.nl Promises and Async 3
Handling Callbacks

• Callback is function that's passed as value to another function :


• Callback will only be executed when event happens
• Simple example with callback is fetching some html page :
//This is just how we include the library we want in CommonJs syntax
const request = require('superagent')
//We send a request to get googles home page
request.get('http://localhost/promises/first.html',(err, res)=> {
// Inside callback! this only gets called once the request finishes
if(err){
// In case something goes wrong, we handle it here
console.error(err)
}
// Once we get the response, we print it to the console
console.log(res.text)
})
console.log("After request is printed first");
• (err, res) argument pattern is signature of callback :
• Error is first argument followed by rest of the arguments Demo03
Async Request

www.spiraltrain.nl Promises and Async 4


Callback Hell

• Main disadvantage of callbacks is callback hell :


• Occurs when you have multiple chained asynchronous task
• Requires defining callback functions within callback functions within callback functions
const verifyUser = function(username, password, callback){
dataBase.verifyUser(username, password, (error, userInfo) => {
if (error) { callback(error)
} else {
dataBase.getRoles(username, (error, roles) => {
if (error){ callback(error)
} else {
dataBase.logAccess(username, (error) => {
if (error){ callback(error);
} else {
callback(null, userInfo, roles);
}
})
}
})
} Demo04
}) Chaining Callbacks
};
www.spiraltrain.nl Promises and Async 5
Promises

• Promise is new standard way of handling async actions :


• Promises were introduced in ECMAScript 2015 and replace callback functions
• Promise is a holder for a result or an error :
• Will become available in the future when the async call returns
• Promises were available in third-party libraries like jQuery and q :
• ECMAScript 6 adds built-in support for promises to JavaScript
• Promisified version of fetching html page looks like this :
const request = require('superagent')
request.get('http://localhost/promises/first.html')
.then((res)=> {
// Once we get the response, we print it to the console
console.log(res.text)
})
Demo05
.catch(err => console.error(err)) Asynchronous Promise

• Signature of promise is then method :


• Callback is argument of then method of promise that asynchronous call returns
www.spiraltrain.nl Promises and Async 6
Promise Chaining

• Promise chaining relieves you from callback hell :


• Attach callbacks to the returned promises forming a promise chain
doSomething().then(function(result) {
return doSomethingElse(result);
})
.then(function(newResult) {return doThirdThing(newResult);})
.then(function(finalResult) {
console.log('Got the final result: ' + finalResult);
})
.catch(failureCallback);
• Arguments to then are optional :
• catch(failureCallback) is short for then(null, failureCallback)
• Can also use arrow functions :
doSomething()
.then(result => doSomethingElse(result))
.then(newResult => doThirdThing(newResult))
.then(finalResult => {
console.log(`Got the final result: ${finalResult}`); Demo06
Promise Chaining
})
.catch(failureCallback);
www.spiraltrain.nl Promises and Async 7
Infinite Chaining

• Promise resolves to future value that they represent :


• Every promise has then method
• then method on being called always returns another promise
• This means it’s possible to infinitely chain then method :
const request = require('superagent')
const nothing = ()=>{}
request.get('http://localhost/promises/first.html')
.then((res)=> {
console.log(res.text)
})
.then(nothing)
.then(nothing)
.then(nothing)
.then(()=> request.get('http://localhost/promises/second.html'))
.then((res)=> {
console.log(res.text) Demo07
}) Infinite Chaining

.catch(err => console.error(err))


www.spiraltrain.nl Promises and Async 8
Creating Promises

• Promises can be created with following syntax :


new Promise(function(resolve, reject) {
// body of function
});

• Function supplied to Promise is executor :


• Function that is passed to other functions via the resolve and reject arguments
• Executor function initiates some asynchronous process :
• Once that completes function calls either resolve or reject function
• resolve for promise's final value, reject it if there is an error
const answerToEverything = new Promise(resolve => {
setTimeout(()=>{
resolve(42)
}, 1000)
})
Demo08
answerToEverything.then(answer => console.log(answer)) Creating Promises
//prints 42
www.spiraltrain.nl Promises and Async 9
Resolving Promises

• then method of promise returns another promise :


• Resolves to value returned by its callback
Demo09
• aNewPromise calls originalPromise’s then method : Resolving Promises

• To return new promise that resolves to “foo”


const aNewPromise = originalPromise.then(someValue=> {
return 'foo'
})
aNewPromise.then(newValue => {
console.log(newValue)
}) // 'foo' is printed on to the console
• containerPromise also resolves to foo :
• containerPromise actually resolves to aNewPromise which resolves to “foo”
const containerPromise = anotherPromise.then(someValue=> { return aNewPromise })
containerPromise.then(newValue => { console.log(newValue)
}) // 'foo' is printed on to the console

www.spiraltrain.nl Promises and Async 10


Catching Errors

• Benefit of promises is multiple promises need not be nested :


• They are linearly chained, and so will never lead you to callback hell
• Promises have common error handling :
• Don’t need to check for errors after each promise like with callbacks
• Possible to chain further after catch :
• Useful to accomplish new actions even after an action failed in the chain
new Promise((resolve, reject) => {
console.log('Initial');
resolve();
})
.then(() => {
throw new Error('Something failed');
console.log('Do this');
})
.catch(() => {
console.log('Do that');
})
Demo10
.then(() => { Catching Errors
console.log('Do this whatever happened before');
});
www.spiraltrain.nl Promises and Async 11
Parallel Execution

• Execute multiple promises in parallel with Promise.all function :

Demo11
Parallel Execution

• Promise.all combines promises getFirstPage and getSecondPage :


• Returns another promise which resolves to an array of results
• Are in same order as original promises
• Promise.all initiates all member promises at same time :
• Combined promise only resolves when all member promises have resolved
• Can combine as many promises as required in this fashion.
www.spiraltrain.nl Promises and Async 12
Promise States

• Promise always exists in one of these states :


• Pending : initial state, not fulfilled nor rejected, do not know what will be outcome
• Fulfilled : operation completed successfully, outcome is succesfull
• Rejected : operation failed, outcome is unsuccessful
• Pending promise can be fulfilled with value or rejected with reason :
• When either occurs handlers associated by promise's then method are called
• At simplest might use promise for case like following :
var prom = new Promise(function(resolve, reject) {
// perform some asynchronous task...
if(/* successful */) {
resolve('success');
} else {
reject('failure');
}
});
prom.then(function() {
/* handle result */
}).catch(function() { /* error */
})
www.spiraltrain.nl Promises and Async 13
Consuming Promises

• Promise is returned object to which you attach callbacks :


• Instead of passing callbacks into a function
• Function that expects two callbacks, and calls one of them on completion or failure
• Old style :
function successCallback(result) {
console.log("It succeeded with " + result);
}
function failureCallback(error) {
console.log("It failed with " + error);
}
doSomething(successCallback, failureCallback)
• New Style :
const promise = doSomething();
promise.then(successCallback, failureCallback);
• Or :
doSomething().then(successCallback, failureCallback); Demo12
Another Promise

www.spiraltrain.nl Promises and Async 14


Promise Guarantees

• Asynchronous function call convention has several advantages :


• Unlike old-style passed-in callbacks, promise comes with some guarantees
• Guarantees :
• Callbacks never called before completion of current run of JavaScript event loop
• Callbacks added with .then :
— Even after success or failure of asynchronous operation will be called as above
• Multiple callbacks may be added by calling .then several times :
— To be executed independently in insertion order
• Most immediate benefit of promises is chaining :
• Common need is to execute more asynchronous operations back to back
• Each subsequent operation starts when the previous operation succeeds
• Can be accomplished by creating promise chain :
• then function returns a new promise different from the original :
const promise = doSomething();
const promise2 = promise.then(successCallback, failureCallback);

www.spiraltrain.nl Promises and Async 15


Promises are Asynchronous

• Consider output of following code :


var ask = function () {
console.log("before");
getPhone
.then(show) // chain it here
.then(function (fulfilled) {
console.log("B");
console.log(fulfilled);
})
.catch(function (error) {
console.log(error.message);
});
console.log("after");
}
ask()
• Output is : before after A B Got black Samsung phone
• Code will run without blocking or waiting for the result :
• Anything that need to wait for promise to proceed, you put that in .then
Demo13
• ES6 code can use arrow functions and const Promises are Asynchronous

www.spiraltrain.nl Promises and Async 16


ES7 Async Await

• ES7 introduce async and await syntax :


• Makes asynchronous syntax look prettier and easier like synchronous code
• To understand without .then and .catch
const request = require('superagent')
async function useAsync() {
const resFirst = await request.get('http://localhost/promises/first.html');
const resSecond = await request.get('http://localhost/promises/second.html');
console.log('First : ', resFirst.text);
console.log('Second :', resSecond.text);
}
useAsync()
• Under the hood there are promises :
• async and await syntax is just syntactic sugar for working with promises
• Function declared to be async :
• Allows you to use await keyword in the body of this function
• await can be put in front of expression evaluating to promise
Demo14
Using Async Await

www.spiraltrain.nl Promises and Async 17


Promises versus Async Await

• Asynchronous tasks with promises :


function asyncTask(i) { return new Promise(resolve => resolve(i + 1)); }
function runAsyncTasks() {
return asyncTask(0)
.then(res1 => { console.log("result1 " + res1); return asyncTask(res1); })
.then(res2 => { console.log("result2 " + res2 ); return asyncTask(res2); })
.then(res3 => { console.log("result3 " + res3 ); return "one with promises";});
}
runAsyncTasks().then(result => console.log(result));
• Asynchronous tasks with async await :
function asyncTask(i) {
return new Promise(resolve => resolve(i + 1));
}
async function runAsyncTasks() {
const res1 = await asyncTask(0); Demo15
Tasks with Promises
const res2 = await asyncTask(res1);
const res3 = await asyncTask(res2);
console.log(`result1, 2, 3 = ${res1} ${res2} ${res3}`);
return "Everything done with asyncawait"; Demo16
} Tasks with Async Await

runAsyncTasks().then(result => console.log(result));


www.spiraltrain.nl Promises and Async 18
Summary : Promises and Async

• JavaScript is synchronous by default and is single threaded :


• Each statement is executed one after the other
• Asynchronous code is code executed when something happens :
• Cannot always wait for events to complete because it takes time
• Callbacks are classical approach to asynchronous programming :
• Provide function as argument to another function that executes an asynchronous task
• Main disadvantage of callbacks is callback hell :
• Occurs when you have multiple chained asynchronous task
• Promises where introduced in ECMAScript 2015 :
• Allow for more readable asynchronous code than is possible with callbacks
• Promise chaining relieves you from callback hell :
• Attach callbacks to the returned promises forming a promise chain
• Promise always exists in one of these states :
• Pending, Fulfilled, Rejected
Exercise 10
• Async/await introduced in ECMAScript 2017 : Promises and Async

• Is just syntactic sugar for working with promises


www.spiraltrain.nl Promises and Async 19

You might also like