Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 81492c7

Browse files
authored
Merge pull request HackYourFuture#40 from remarcmij/master
Updated/added fundamentals. Further suggested changes: Swap week 7 & 8 topics. Do XMLHttpRequest in week 7 and combine with promises, leaving more time in JS3 to do promises homework and exercises. We need XMLHttpRequest here because at this point in the curriculum it is the only realistic use case for promises.
2 parents a0a38a6 + d67409e commit 81492c7

12 files changed

+274
-39
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Here you can find course content and homework for the JavaScript 1,2 and 3 modul
1515
|6.|[Closures](fundamentals/scope_closures_this.md) <br>• Callbacks|[Reading Week 6](/Week6/README.md)|[Homework Week 6](/Week6/MAKEME.md)|
1616
|7.|[Object Oriented Programming and Classes](fundamentals/oop_classes.md)<br>• [The `this` keyword](fundamentals/this.md) |[Reading Week 7](/Week7/README.md)|[Homework Week 7](/Week7/MAKEME.md)|
1717
|8.|• Structure for a basic SPA (Single Page Application) <br>• [XMLHttpRequests](fundamentals/XMLHttpRequest.md) <br>• API calls|[Reading Week 8](/Week8/README.md)|[Homework Week 8](/Week8/MAKEME.md)|
18-
|9.|[Promises](fundamentals/promises.md)<br> • (re)writing data structures (in JSON) <br>• Async vs Sync <br>• Code flow (order of execution) |[Reading Week 9](/Week9/README.md)|[Homework Week 9](/Week9/MAKEME.md)|
18+
|9.|[Promises](fundamentals/promises.md)<br> • (re)writing data structures (in JSON) <br>• Async vs Sync <br>• [Event Loop (order of execution)](fundamentals/event_loop.md) |[Reading Week 9](/Week9/README.md)|[Homework Week 9](/Week9/MAKEME.md)|
1919

2020
__Kind note:__
2121

fundamentals/assets/call-stack.png

12.9 KB
Loading

fundamentals/assets/event-loop-1.png

29.7 KB
Loading

fundamentals/assets/event-loop-2.png

20.3 KB
Loading

fundamentals/assets/event-loop-3.png

32 KB
Loading

fundamentals/assets/event-loop-4.png

25.3 KB
Loading

fundamentals/assets/event-loop-5.png

8.34 KB
Loading

fundamentals/assets/sync-async.png

12.1 KB
Loading

fundamentals/event_loop.md

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
# Event Loop
2+
3+
## YouTube Video
4+
5+
This article is a companion to the excellent YouTube video [What the heck is the event loop anyway?](https://www.youtube.com/watch?v=8aGhZQkoFbQ) by Philip Roberts.
6+
7+
[![Event Loop](https://img.youtube.com/vi/8aGhZQkoFbQ/0.jpg)](https://www.youtube.com/watch?v=8aGhZQkoFbQ "Event Loop")
8+
9+
## Introduction
10+
11+
The way of programming when developing JavaScript applications for the browser is sometimes called _Event-Driven Programming_. Once a JavaScript program has been loaded in the browser and has completed its initialization, it is normally waiting for specific "events" to happen. These events can take the form of mouse movements and clicks, keyboard interactions and network-related events (e.g. a response from an `XMLHttpRequest`)*.
12+
13+
In order for a JavaScript program to respond to a specific (type of) event, a programmer needs to add an "event listener" for the event type of interest to the target DOM element or network request object.
14+
15+
Event examples are:
16+
17+
- a `'click'` event from an HTML button element.
18+
- a `'load'` event from an XMLHttpRequest.
19+
20+
A JavaScript program can also set up one or more timers and execute a function when a specific timeout expires. One could consider these to be _software-initiated_ events.
21+
22+
When a event occurs, the browser places an object with information about the event along with the JavaScript function designated to handle the event in an Event Queue. When the JavaScript engine is idle (i.e. when the call stack is empty, see below), it picks up the next event from the Event Queue and invokes the corresponding event handler, passing the event object as a parameter. This mechanism could be depicted by the follow pseudo-code:
23+
24+
```
25+
// Event Loop
26+
while (waiting_for_event) {
27+
execute_event_handler(event)
28+
}
29+
```
30+
31+
32+
\* Note: There are more [Web APIs](https://developer.mozilla.org/en-US/docs/Web/API) available in the browser that could potentially generate events, e.g. the [SpeechSynthesis API](https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesis) and the [MIDIAccess API](https://developer.mozilla.org/en-US/docs/Web/API/MIDIAccess), to name just two.
33+
34+
## Call Stack
35+
36+
The JavaScript engine maintains a [call stack](https://developer.mozilla.org/en-US/docs/Glossary/Call_stack) to keep track of nested function calls. (The call stack is similar to a JavaScript array to which items are pushed and from which items are popped.)
37+
38+
Figure 1 below depicts the call stack for a scenario where function **A**() calls function **B**(). The currently executing function is always the one at the top of the call stack. In this case, execution starts with function **A**().
39+
40+
1. The JavaScript engine pushes **A**() on the call stack and starts its execution.
41+
2. Function **A**() calls function **B()**: the JavaScript engine suspends the execution of **A**() (taking note where it left off), pushes **B**() on the call stack and starts executing **B**().
42+
3. When function **B**() returns, the JavaScript engine pops **B**() off the stack. Since function **A**() is now again at the top the stack, the JavaScript engine resumes **A**() at the point where it left off.
43+
4. Finally, when function **A**() returns it is popped of the stack and with the call stack now empty, the JavaScript engine enters its event loop.
44+
45+
![Call Stack](assets/call-stack.png)
46+
47+
Figure 1. Call Stack
48+
49+
## Example Code
50+
51+
We will use the example application below for our discussion of the event loop. The application consist of a simple HTML page with three buttons and an associated JavaScript file. The web page looks like this:
52+
53+
![Syn/Async Demo Page](assets/sync-async.png)
54+
55+
All output resulting from button clicks will be printed in the browser's console.
56+
57+
### index.html
58+
59+
```html
60+
<!DOCTYPE html>
61+
<html>
62+
<head>
63+
<title>Sync/Async Demo</title>
64+
<style>
65+
button {
66+
margin-right: 4px;
67+
}
68+
</style>
69+
</head>
70+
<body>
71+
<div>
72+
<h1>Sync/Async Demo</h1>
73+
<button id="btn-sync">START SYNC TIMER</button>
74+
<button id="btn-async">START ASYNC TIMER</button>
75+
<button id="btn-hello">HELLO</button>
76+
</div>
77+
<script src="app.js"></script>
78+
</body>
79+
</html>
80+
```
81+
82+
### app.js
83+
84+
The JavaScript file `app.js` adds a `'click'` event listener for each of the three buttons. Rather than using anonymous functions for the event handlers, all functions are given a name so that these names show up in the call stack should we run this code in the Chrome debugger.
85+
86+
```js
87+
'use strict';
88+
'use strict';
89+
{
90+
function synTimeout(delay) {
91+
const stopTime = Date.now() + delay;
92+
while (Date.now() < stopTime);
93+
}
94+
95+
function addSyncOnClickListener() {
96+
document
97+
.getElementById('btn-sync')
98+
.addEventListener('click', function onSyncClick() {
99+
console.log('start sync timer');
100+
synTimeout(5000);
101+
console.log('stop sync timer');
102+
});
103+
}
104+
105+
function addAsyncOnClickListener() {
106+
document
107+
.getElementById('btn-async')
108+
.addEventListener('click', function onAsyncClick() {
109+
console.log('start async timer');
110+
setTimeout(function onTimeout() {
111+
console.log('stop async timer');
112+
}, 5000);
113+
});
114+
}
115+
116+
function addHelloOnClickListener() {
117+
document
118+
.getElementById('btn-hello')
119+
.addEventListener('click', function onHelloClick() {
120+
console.log('Hello, world!');
121+
});
122+
}
123+
124+
window.onload = () => {
125+
addSyncOnClickListener();
126+
addAsyncOnClickListener();
127+
addHelloOnClickListener();
128+
};
129+
}
130+
```
131+
132+
### Synchronous, blocking code
133+
134+
In Figure 2.1 below, when the **START SYNC TIMER** button is clicked ①, a `click` event with its `onSyncClick` event handler is placed in the Event Queue and, because the call stack is empty, is immediately executed. The `onSyncClick` function calls the `synTimeout` function, passing the desired time delay in milliseconds in the `delay` parameter. The call stack at this point in time is depicted in ②.
135+
136+
The `synTimeout` function keeps racing around in a tight `while` loop, in each loop iteration calling `Date.now()` to check whether the specified delay has already been reached. While the JavaScript engine is busy executing this `while` loop, it cannot run any other code. In particular, it cannot pick up events from the Event Queue, for instance click events from the **HELLO** button, while the loop is executing ③. The `onHelloClick` event handler awaits execution in the Event Queue (with the browser appearing to be unresponsive) until the `synTimeout` function completes, and with it, the `onSyncClick` function (Figure 2.2, ④).
137+
138+
![Event Loop 1](assets/event-loop-1.png)
139+
140+
Figure 2.1 The Event Loop - blocking code.
141+
142+
At this point the call stack becomes empty, and the event loop can pick up `onHelloClick` from the Event Queue and execute it ⑤. In the browser this is experienced as a delayed, sluggish response to the click on the **HELLO** button.
143+
144+
Finally, when the `onHelloClick` event handler has finished execution, the call stack becomes empty again ⑥, and the event loop awaits further, future events.
145+
146+
**In conclusion:** Synchronous, blocking code, such as implemented by
147+
the `synTimeout` function is to be avoided as it makes the application appear to be unresponsive.
148+
149+
![Event Loop 2](assets/event-loop-2.png)
150+
151+
Figure 2.2 The Event Loop - blocking code - continued.
152+
153+
## Asynchronous, non-blocking code
154+
155+
In contrast, in Figure 3.1, when we click the **START ASYNC TIMER** button ①, the `onAsyncClick` event handler is placed and the Event Queue and, because the call stack is empty, is immediately executed ②. It in turn calls the `setTimeout` function provided by the browser (**not** the JavaScript engine!). This starts a timer internal to the browser ③. Once the timer has been set up the `setTimeout` function returns and subsequently the `onAsyncClick` event handler exits.
156+
157+
Suppose that one second later we click the **HELLO** button ④. This causes the `onHelloClick` event handler to be placed in the Event Queue. Because the call stack is empty the `onHelloClick` event handler is immediately executed ⑤ and subsequently exits.
158+
159+
![Event Loop 3](assets/event-loop-3.png)
160+
161+
Figure 3.1 The Event Loop - non-blocking code.
162+
163+
164+
When some time later the timer set up in step 3 expires, the `onTimeout` callback is placed in the event queue ⑥. Again, because the call stack is empty at that point in time it is immediately executed ⑦.
165+
166+
![Event Loop 4](assets/event-loop-4.png)
167+
168+
Figure 3.2 The Event Loop - non-blocking code - continued.
169+
170+
Subsequently it exits, leaving the call stack empty again ⑧, ready to take on new events from the event loop whenever they occur.
171+
172+
![Event Loop 5](assets/event-loop-5.png)
173+
174+
Figure 3.3 The Event Loop - non-blocking code - continued.
175+
176+
**In conclusion:** Asynchronous, non-blocking code is to be preferred at all times to ensure that the application maintains its responsiveness.
177+
178+
## More Information
179+
180+
Mozilla Developer Network: [Concurrency model and Event Loop](https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop)

fundamentals/map_filter.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,9 @@ Result:
199199

200200
### Method chaining
201201

202-
The methods **map()**, **filter()** and **reduce()** each return a new array. This makes it possible to chain these methods and create a 'pipeline' of operations, to be applied in sequence. Let's take the last example, but now filtering out only those array elements for which the name starts with a 'J':
202+
The methods **map()** and **filter()** each return a new array. This makes it possible to chain these methods and create a 'pipeline' of operations, to be applied in sequence. The **reduce** method can return anything, including an array. If a **reduce** method returns something other than an array it can only be included at the end of an array method chain.
203+
204+
Let's take the last example, but now filtering out only those array elements for which the name starts with a 'J':
203205

204206
```js
205207
const arr = [

fundamentals/oop_classes.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ months
216216

217217
![prototype](assets/prototype.png)
218218

219-
### Prototype vs __prototype
219+
### Prototype vs \_\_prototype\_\_
220220

221221
The above diagram depicts how this sharing works out.
222222

0 commit comments

Comments
 (0)