js-client-side
js-client-side
function f() {
console.log(‘beginning');
function callback1() {
console.log('callback1');
}
setTimeout(callback1, 1000); //1s
console.log('middle');
function callback2() {
console.log('callback2');
}
setTimeout(callback2, 2000); //2s
console.log('end');
}
f();
3
Review: Exam-style Exercise
• What is the output of this code?
• Closures
• Frameworks
7
Review: Event-driven programming
let count = 0;
function callback() {
count++;
if (count < 2) {
setTimeout(callback, 0);
}
console.log(count);
}
setTimeout(callback, 0);
// what will print?
8
Common mistake: for-in loops
• for-in loops often yield unexpected results
• They iterate "up the prototype chain"
> const chickens = ['Magda', 'Marilyn', 'Myrtle II'];
> for (let chicken in chickens) {
> console.log(chicken);
> }
1
2
3
• ES6's for-of loops are nice, but are hard to analyze statically, so some style
guides do not allow them
> for (let chicken of chickens) {
> console.log(chicken);
> }
Magda
Marilyn
Myrtle II
10
Iteration with forEach and map
• forEach loops "do the right thing"
• Behave like other programming languages (C, C++, Perl, Python ...)
• We'll learn about the => syntax soon (it's an anonymous function)
const chickens = ['Magda', 'Marilyn', 'Myrtle II’];
chickens.forEach((chicken) => {
console.log(chicken);
});
11
JavaScript: functional programming
• In functional programming, execution occurs by composing functions
together rather than executing sequences of statements
• Example:
12
JavaScript: functional programming
• In functional programming, execution occurs by composing functions
together rather than executing sequences of statements
• Example (alternate):
13
JavaScript: Functional programming??
• Consider this scenario:
• User clicks a button
• Browser sends a POST request
• Browser waits for server response
• Browser renders changes in DOM tree
• Looks something like this in JavaScript:
14
JavaScript: Functional programming??
• Consider this scenario:
• User clicks a button
• Browser sends a POST request
• Browser waits for server response
• Browser renders changes in DOM tree
• Looks something like this in JavaScript:
15
JavaScript: Functional programming
• Note: the onclick function handler runs when the button gets clicked
• We don’t want the browser to “freeze” when the user clicks the button
• Instead, we schedule events in the event queue to occur:
• Immediately make a POST request
• Schedule a onSuccessFunction to run when the request finishes
• Schedule a onFailFunction to run if the request fails (e.g., server doesn’t respond)
• This way, we don’t have to wait around for the server on every UI event
16
Outline
• Review: event-driven programming
• Closures
• Frameworks
17
DOM Review html
<html>
<head></head> head body
<body>
<div id="content">
<p>Drew DeOrio</p>
<p>Jason Flinn</p> div
id=“content”
</div>
</body>
</html>
p p
Drew Jason
18
Overview
• Turn JSON data into a webpage that looks like this
{
"url": "/u/1/",
"username": "awdeorio"
},
{
"url": "/u/2/",
"username": "jflinn"
}
<html>
<head></head>
<body>
<div id=“content”>
<p class=“user”>awdeorio’s link <a href=“/u/1/”>here</a></p>
<p class=“user”>jflinn’s link <a href=“/u/2/”>here</a></p>
</div>
</body>
</html>
19
20
Outline
• Review: event-driven programming
• Closures
• Frameworks
23
Fetch
• JavaScript provides a “fetch” API for making HTTP requests
• These do not require browser reloads
24
Fetch API
• How JavaScript requests data from a REST API
• JavaScript function that loads data from the server
• Returns a "promise"
fetch("https://dijkstra.eecs.umich.edu/kleach/eecs485/su20/s/users.json")
.then(handleResponse)
.then(handleData);
25
Promises
• Promise: a function that returns some time in the future
• Put a function call on the event queue
• Needed for fetch because request/response is not instant
• Recall: JavaScript is single-threaded. We don’t want the UI to freeze up while
the request is being serviced
fetch("https://dijkstra.eecs.umich.edu/kleach/eecs485/su20/s/users.json")
.then(handleResponse)
.then(handleData);
26
Outline
• Review: event-driven programming
• Closures
• Frameworks
32
Closures
function outer() {
let x = 0;
function inner() {
x++;
console.log(x);
}
return inner;
}
let f = outer();
f();
f();
33
Closures
• Notice that the inner function has access to outer function's variables
• Lexically scoped name binding
• This is called a closure
function showUsers() {
const entry = document.getElementById('JSEntry');
//...
function handleData(data) {
//...
entry.appendChild(node);
}
fetch(/* ... */) // ...
}
34
Closures
function showUsers() {
const entry = document.getElementById('JSEntry');
function handleResponse(response) { /*... */ }
function handleData(data) {
// ...
entry.appendChild(node);
}
fetch(/*...*/)
.then(handleResponse)
.then(handleData)
.catch(error => console.log(error));
}
• The inner function has a longer lifetime than the outer function
• handleData() has access to entry even though showUsers() has already
returned!
35
function showUsers() {
const entry = /*...*/;
function handleData(data) {
// ...
1. Objects created for entry, }
entry.appendChild(node);
36
Why closures important in web development
• Callback Functions are everywhere
• Event handlers: click
• Promise handlers: .then()
41
Anonymous functions
• These callback functions are used only once
function showUsers() {
const entry = document.getElementById('JSEntry');
fetch('/api/v1/users/')
.then(handleResponse)
.then(handleData);
}
42
Anonymous functions
• Refactor to use anonymous functions
function showUsers() {
const entry = document.getElementById('JSEntry');
fetch('/api/v1/users/')
.then(function(response) {
//...
})
.then(function(data) {
//...
})
}
43
Anonymous functions
• Works exactly the same way as when the functions had names
• Also called a lambda function or function literal
function showUsers() {
const entry = document.getElementById('JSEntry');
fetch('/api/v1/users/')
.then(function(response) {
//...
})
.then(function(data) {
//...
})
}
44
Anonymous functions in ES6
• ES6 provides a convenient syntax for anonymous functions
• "Arrow functions"
function showUsers() {
const entry = document.getElementById('JSEntry');
fetch('/api/v1/users/')
.then((response) => {
//...
})
.then((data) => {
//...
})
}
45
Anonymous functions in ES6
• Anatomy of an anonymous function
• Inputs
• Body
• Arrow
• Creates a function object on the heap
• Just like "regular" functions
• Long format
(INPUTS) => {
// BODY
}
• Short cut for body with one function call
INPUT => my_function(INPUT)
46
Outline
• Review: event-driven programming
• Closures
• Frameworks
47
A problem with raw JavaScript
• Large JavaScript applications quickly become unwieldly
• All functions act on the DOM, DOM acts like a giant global variable
• Difficult to decompose program into abstractions
function showUser() {
fetch()
.then(function(data) {
const users = data.results;
users.forEach((user) => {
const node = document.createElement('p');
//...
node.appendChild(textnode);
entry.appendChild(node);
});
})
//...
48
React
• React is a framework built by Facebook
• Build encapsulated components that manage their own state
• Compose them to make complex UIs
• Efficient updates to the DOM
• https://reactjs.org/
49
React
• Components
• Functional: usually stateless
• Class-type: usually stateful
• Tree of composable components -> DOM
50
Virtual DOM
• Components rendering cause other components to render
• This would cause lots of DOM updates, which are slow
• Because the actual screen changes
• Solution: a Virtual DOM
• Live example
https://codepen.io/awdeorio/pen/yzXjzZ?editors=1010
52