Download as pdf or txt
Download as pdf or txt
You are on page 1of 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