You are on page 1of 19

Asynchronous functions & API

calls
Introduction

 Javascript is a single threaded programming


language
 No concurrency issues with single threaded
language, but this means that long
operations like accessing APIs will block the
main thread
 Using asynchronous Javascript, you can
perform such operations without blocking
the main thread
Understanding Asynchronous
functions
const networkRequest = (url) => {
/* connect to some server and get data  This takes some time and
*/ runs asynchronously
return someData;
}

const greeting = (data) => {


console.log(“Hello “+data);
}

var data =
networkRequest(“www.someurl.com”);
 greeting() is executed
immediately, so data will be
greeting(data);
undefined.
Using callbacks
networkRequest 2nd
const networkRequest = (url, callback) => { parameter is callback,
/* connect to some server and get data */ which should be a
//somedata is retrieved from the server function.
 callback is called
callback(somedata); when function is
} completed

const greeting = (data) => {


console.log(“Hello “+data);
}

var data = networkRequest(“www.someurl.com”, greeting is passed as


greeting); callback, and will be
executed by
networkRequest
Using callbacks
//3 steps
const step1= (num, callback) => {
setTimeout(() => {
console.log(“step”+num);
callback(++num, this.step3);
}, 2000);
}
const step2= (num, callback)=> {
setTimeout(()=> {
console.log(“step”+num);
callback(++num);
}, 2000);
}

const step3 = (num)=> {


setTimeout(()=> {
console.log(“step”+num);
}, 2000);

}
step1(1, this.step2);
Introduction to Promises

 Promises have been introduced natively in ES6


 Promises are like event listeners, in that they will
trigger when an event is complete, except that:
 A promise can only succeed or fail once. It cannot
switch from success to failure or vice versa
 If a promise has succeed or failed and later your add a
success/failure callback, the correct callback will be
called, even though the event took place earlier
Introduction to Promises
var promise = new Promise(function(resolve, resolve and reject are
reject) { callbacks that will be
if(success) { called in the event of
resolve(“It works”); success or failure
}
else {
reject(“It failed”);
}
}
Use the promise.
promise.then(function(result) { Passing in callbacks are
console.log(result); //it works optional.
}, function(err) {
console.log(err); //it failed
});
Chaining promises

 If your resolve function returns a value, you


can chain multiple “then” together
var adding = new Promise(function(resolve, reject) {
resolve(1);
}
adding.then(function(val){
console.log(val) //1
return val + 2;
}).then(function(val) {
console.log(val); //3
});
Multiple Promises

 Instead of chaining Promises one after


another, you might want to run a set of
promises simultaneously, and only need to
know when all have been resolved.
 Promises.all accepts an array of promises ,
and resolves when all have been completed
 This reduces the time taken as multiple
promises can run asynchronously
Promise.all example
const timer1 = new Promise((resolve,reject) => {
var time = 100 + parseInt(Math.random() * const timer3 = new
100); Promise((resolve,reject) => {
setTimeout(()=>{
var time = 100 + parseInt(Math.random()
console.log(“Timer1 complete”);
resolve();
* 100);
}, time); setTimeout(()=>{
}); console.log(“Timer3 complete”);
resolve();
const timer2 = new Promise((resolve,reject) => { }, time);
var time = 100 + parseInt(Math.random() * });
100);
setTimeout(()=>{
console.log(“Timer2complete”);
Promise.all([timer1, timer2,
resolve(); timer3]).then(() => {
}, time); console.log(“All complete!”);
}); });
Using Fetch

 fetch is a native javascript function used for


making HTTP requests and parsing responses
 fetch returns a Promise

fetch(‘http://example.com/test.json’)
.then(response => response.json())
.then(data => console.log(data));
Using Fetch Api
 Fetching data from data.gov.sg
 Moment is a library for parsing dates and times
(www.momentjs.com)
var today = moment().format(“YYYY-MM-DD”);
fetch(“https://api.data.gov.sg/v1/environment/psi?date=“+today, {
method:’GET’}
).then(response => response.json())
.then(data => {

console.log(“Today’s national PSI is “+data.items[0].readings.


psi_twenty_four_hourly.national);
});
“Callback hell”
 “Callback hell” is a term used when the code has to use multiple sequential
callbacks, one after another, resulting in difficult to read code.

 Consider the following:


var x = getValueFromServer();
var y = x + getValueFromServer2();
var z = y + getValueFromServer3();

 Using callbacks:
fetch(“/server/call1”).then(response => {
      fetch(“/server/call2”).then(response2 => {
            fetch(“/server/call3”).then(response3 =>{
                    var z = response + response2 + response3;
      }
   }
});
Async and await

var x = await fetch(“/server/call1”);


var y = await fetch(“/server/call2”);
var z = await fetch(“/server/call3”);
console.log(x+ y + z);
Async and await example
var today = moment().format(“YYYY-MM-DD”);
var response = await fetch(“https://api.data.gov.sg/v1/environment/psi?
date=“+today, {
method:’GET’}
);
var psiJson =await response.json();
var yesterday = moment().subtract(1, ‘days’).format(“YYYY-MM-DD”);
var response2 =await fetch(“https://api.data.gov.sg/v1/environment/psi?
date=“+yesterday, {
method:’GET’}
);
var psiJson2 = await response2.json();
var psiDifference = psiJson.items[0].readings. psi_twenty_four_hourly.national–
psiJson2.items[0].readings. psi_twenty_four_hourly.national;
console.log(“Difference in PSI is “+psiDifference);
Loops with Promises

 It is important to know what the result of


calling an asynchronous function in a loop
 You can loop through an array using a for-
loop or array.forEach
var data = [item1, item2, item3]

for(const i=0; i < data.length; i++){


await sendToServer(data[i]);
}

data.forEach(async (item) => {


await sendToServer(item);
});
Loops with Promises
1. using forEach, the function calls are called without waiting for the previous one

var number = 0;
var data = [50, 100, 150];
async function delay(){
return new Promise(resolve => setTimeout(resolve, 300));
}

async function delayAdd(item){


await delay(); Output:
number += item; 0
console.log(number); 50
} 150
data.forEach(async (item) => { 300
await delayAdd(item);
});

console.log(number);
Loops with Promises
2. Using a for-loop processes the array in sequence

for(const item of data){


await delayAdd(item);
}
console.log(num);

Output:
50
150
300
300
Loops with Promises

3. Process all at the same time and resolve


when all have completed

const promises = data.map(delayedAdd);


await Promise.all(promises);
console.log(num);

You might also like