You are on page 1of 53

WEB PROGRAMMING

ASYNCHRONOUS PROGRAMMING, AJAX.


ADDITIONAL LANGUAGE ELEMENTS, THIS, EXCEPTIONS
Győző Horváth
associate professor
gyozo.horvath@inf.elte.hu

1117 Budapest, Pázmány Péter sétány 1/c., 4.725

1
RECAP

2
RECAP
 JavaScript language elements
 DOM programming
 Event handling details
 Code structure
 Forms, images, tables
 JavaScript beépített objektumai
 Canvas, animations, HTML5 APIs

3
JSON

4
JSON
JavaScript Object Notation
Data description format
Widely used and popular
A data format based on JavaScript literals
Central elements
simple types
objects: {}
array: []
JSON.stringify()
JSON.parse()

5
JSON - EXAMPLE
{
"Title": "The Hobbit: An Unexpected Journey",
"Year": "2012",
"Rated": "PG-13",
"Released": "14 Dec 2012",
"Runtime": "169 min",
"Genre": "Adventure, Fantasy",
"Director": "Peter Jackson",
"Language": "English",
"Country": "USA, New Zealand",
"Poster": "https://m.media-amazon.com/images/<...>",
"Ratings": [
{
"Source": "Internet Movie Database",
"Value": "7.8/10"
},
{

6
JSON SERIALIZATION AND DESERIALIZATION
const data = {
foo: "string",
bar: [1, 2, 3]
}

// Serialization
const serializedData = JSON.stringify(data);
console.log(serializedData);
// '{"foo":"string","bar":[1,2,3]}'

// Deserialization
const deserializedData = JSON.parse(serializedData);
console.log(deserializedData);
// Object { foo: "string", bar: Array[3] }

7
SYNCHRONOUS VS
ASYNCHRONOUS PROGRAMMING

8
SYNCHRONOUS OPERATIONS
Synchronous ~ synchronized ~ connected ~ dependent
Synchronous operation: must wait for the end of an
operation before jumping to the next one
The beginning of one operation depends on the end of the
other
Sequence

9
SYNCHRONOUS EXAMPLE
console.log("first");
alert("second");
console.log("third");

Alert

10
SYNCHRONOUS EXECUTION

11
12
DISADVANTAGE OF SYNCHRONOUS
OPERATIONS
Waiting for long operations
timers
network
disk I/O

13
ASYNCHRONOUS
You can start another task before finishing one task
They do not depend on each other

14
SYNCHRONOUS VS ASYNCHRONOUS

15
EXAMPLE: SYNCHRONOUS VS ASYNCHRONOUS
Synchronous
You are in a queue to get a movie ticket. You cannot get one until
everybody in front of you gets one, and the same applies to the
people queued behind you.
Asynchronous
You are in a restaurant with many other people. You order your
food. Other people can also order their food, they don’t have to
wait for your food to be cooked and served to you before they
can order. In the kitchen restaurant workers are continuously
cooking, serving, and taking orders. People will get their food
served as soon as it is cooked.

16
EXAMPLE: SYNCHRONOUS VS ASYNCHRONOUS
Synchronous My boss is a busy man. He tells me to write the
code. I tell him: Fine. I get started and he’s watching me like a
vulture, standing behind me, off my shoulder. I’m like “Dude, why
don’t you go and do something while I finish this?” He’s like: “No,
I’m waiting right here until you finish.”
Asynchronous The boss tells me to do it, and rather than waiting
right there for my work, the boss goes off and does other tasks.
When I finish my job I simply report to my boss and say: “I’m
DONE!”

17
EXAMPLES OF ASYNCHRONOUS OPERATIONS
Alert
// Timer
console.log("first");

setTimeout(function () {
console.log("second");
}, 1000);

console.log("third");

Alert
// Event handler
console.log("first");

button.addEventListener("click", function () {
console.log("second");
});

console.log("third");

18
EVENT LOOP
Concurrency on a single thread

19
20
CALLBACK FUNCTION
Calling a function as a parameter
Not synchronous/asynchronous itself
The API is synchronous/asynchronous
// Syncronous
function a(b) {
b(); // callback
} // Asyncronous
console.log("first");
console.log("first");
a(function () { setTimeout(function () {
console.log("second"); console.log("second");
}); }, 1000);
console.log("third");
console.log("third");
// OR

[1, 3, 5].map(e => e * 2);

21
PROBLEM: CALLBACK HELL
setTimeout(() => {
console.log("first");
setTimeout(() => {
console.log("second");
setTimeout(() => {
console.log("third");
setTimeout(() => {
console.log("fourth");
},1000);
}, 1000);
}, 1000);
}, 1000);

22
SOLUTION: PROMISE
An object representing the future value of an asynchronous
operation
States: pending , fulfilled , rejected
Methods: .then() , .catch()
function delay(ms) {
return new Promise(function (resolve, reject) {
setTimeout(() => {
console.log(`${ms} timeout`);
resolve(ms);
}, ms);
});
}

// USAGE

delay(1000).then(ms => console.log("Result", ms));

23
PROMISE CHAIN
delay(1000)
.then((ms) => { return delay(500); })
.then((ms) => { return delay(2000); })
.then((ms) => { return 800; })
.then((ms) => { console.log("Finally", ms); })
.catch(() => {
console.log("There are some errors");
});

24
ASYNC - AWAIT
Part of the standard since ES8 (2017)
Works with Promises
async function lotOfDelays() {
try {
await delay(500);
await delay(2000);
const ms = await delay(800);
console.log("Finally", ms);
} catch {
console.log("There are some errors")
}
}

lotOfDelays();

25
WEB WORKERS
Real multithreading
Communication: messages/events
// Main thread
const worker = new Worker("worker.js");

worker.onmessage = function(e) {
console.log(e.data);
};

worker.postMessage("some data");

// worker.js
self.onmessage = function(e) {
self.postMessage("Recieved data: " + e.data);
};

26
AJAX AND FETCH

27
TRADITIONAL WEB PAGES

28
AJAX WEB PAGES

29
AJAX
Asynchronous JavaScript and XML
Communication with the server is necessary
Only transmitting the required data in the background
Without reloading the entire page

30
PROPERTIES OF AN AJAX PAGE
The user interface can be used continuously
No blinking, jumping
Communication with the server takes place in the
background
Asynchronously, ie in parallel with other events
Only the necessary data is transmitted between the server
and the client

31
AJAX TOOLS
API
XMLHttpRequest object and usage
fetch and usage
Developer toolbar
Network tab

32
EXAMPLE
http://www.omdbapi.com/?t=the+shack&apikey=<key>

The Shack Search

33
SYNCHRONOUS SOLUTION
const input = document.querySelector("input");
const button = document.querySelector("button")
const img = document.querySelector("img");

button.addEventListener("click", getPoster);
function getPoster() {
const title = input.value;

const xhr = new XMLHttpRequest();

xhr.open("GET", `http://www.omdbapi.com/?t=${
xhr.send(null);

const response = JSON.parse(xhr.responseText)


img.src = response.Poster;
}

34
ASYNCHRONOUS SOLUTION
load , loadend , abort , error , timeout events
function getPoster() {
const title = input.value;
const xhr = new XMLHttpRequest();

xhr.addEventListener("load", responseHandler);
xhr.open("GET", `http://www.omdbapi.com/?t=${title}&apikey=<k
xhr.send(null);
}

function responseHandler() {
const response = JSON.parse(this.responseText)
img.src = response.Poster;
}

35
RESPONSE TYPES
responseType , response
function getPoster() {
const title = input.value;
const xhr = new XMLHttpRequest();

xhr.addEventListener("load", responseHandler)
xhr.open("GET", `http://www.omdbapi.com/?t=${title}&apikey=<k
xhr.responseType = "json";
xhr.send(null);
}

function responseHandler() {
img.src = this.response.Poster;
}

36
ERROR HANDLING
function getPoster() {
const title = input.value;
const xhr = new XMLHttpRequest();

xhr.addEventListener("load", responseHandler);
xhr.addEventListener("error", errorHandler);
xhr.open("GET", `http://www.omdbapi.com/?t=${title}&apikey=<k
xhr.responseType = "json";
xhr.send(null);
}
function errorHandler() {
console.error("Error");
}
function responseHandler() {
img.src = this.response.Poster;
}

37
PROGRESS
progress event
const progress = document.querySelector("progress");

function getPoster() {
const title = document.querySelector("input").value;
const xhr = new XMLHttpRequest();

xhr.addEventListener("load", responseHandler);
xhr.addEventListener("progress", progressHandler);
xhr.open("GET", `http://www.omdbapi.com/?t=${title}&apikey=<k
xhr.responseType = "json";
xhr.send(null);
}
function progressHandler(e) {
if (e.lengthComputable) {
progress.max = e.total;
progress.value = e.loaded;
}

38
FETCH API
Works with Promises
function getPoster() {
const title = document.querySelector("input").value;
fetch(`http://www.omdbapi.com/?t=${title}&apikey=2dd0dbee`)
.then(response => response.json())
.then(response => {
document.querySelector("img").src = response.Poster;
});
}

// OR

async function getPoster() {


const title = document.querySelector("input").value;
const response = await fetch(`http://www.omdbapi.com/?t=${tit
const json = await response.json();
document.querySelector("img").src = json.Poster;
}

39
this -LEXIA

A.K.A. THE CONTEXT OF this

40
THE CONTEXT OF this
//Global
let name = 'Peter'; // window.name
function hello() {
return this.name // this === global (window)
}
hello() // window.hello()

//Method call
let peter = {
name: 'Peter',
describe: function () {
return this.name // this === peter
}
}
peter.describe()

//Constructor call

41
LOSING CONTEXT
let peter = {
name: 'Peter',
age: 42,
describe: function () {
function getAge() {
return this.age // this === global (window)
}
return this.name + ':' + getAge() // global call, ~ win
}
}
peter.describe() // "Peter:undefined"

42
RESTORE THE CONTEXT OF THIS FOR INNER
FUNCTIONS
//With call and apply
let peter = {
name: 'Peter',
age: 42,
describe: function () {
function getAge() {
return this.age // this depends on the call
}
return this.name + ':' + getAge.call(this)
}
}
peter.describe() // "Peter:42"

//ES5 bind()
let peter = {
name: 'Peter',
age: 42,

43
EXAMPLE: document.querySelector
const $ = document.querySelector;
$('p') // Illegal invocation

// Explanation
const document = {
somethingInside: ...,
querySelector: function (sel) {
this.somethingInside
}
}
document.querySelector() // --> this === document
window.$() // --> this === window, no window.somethingInside

// Solution: fixing the context


const $ = document.querySelector.bind(this);

44
EXAMPLE: IN-CLASS EVENT HANDLERS
// Starting point
class AppView {
constructor(appState) {
this.elem = document.querySelector('something')
this.elem.addEventListener('click', this.onClick)
}
onClick(e) {
// this === document.querySelector('something')
}
}

// Bind
class AppView {
constructor(appState) {
this.elem = document.querySelector('something')
this.elem.addEventListener('click', this.onClick.bind(this)
}

45
EXCEPTION HANDLING

46
ERROR TYPES
Error
EvalError
RangeError Tulajdonságok
ReferenceError name
SyntaxError message
TypeError
URIError

47
EXCEPTION HANDLING
try-catch-finally
try : code to protect
catch : error handling code
finally : code running at the end (optional)
try {
foo.bar = true;
} catch (e) {
console.log(e.name); // ReferenceError
console.log(e.message); // foo is not defined
} finally { // Optional
console.log("Finally...");
}

48
THROWING ERRORS
Built-in errors
if (typeof a !== "number") {
throw new Error("Argument is not a number!");
}

49
THROWING ERRORS
Custom error objects
if (divisor == 0) {
throw {
name: "DivisionByZeroError",
message: "Division by zero!"
};
}

vagy
class DivisionByZeroError extends Error() {}

if (divisor === 0) {
throw new DivisionByZeroError("Division by zero!");
}

50
SUMMARY
Synchronous and asynchronous operations
Promises
Async-await
AJAX / Fetch
The context of this
Exception handling

51
52

You might also like