Skip to content

Commit fbce9cf

Browse files
authored
Merge pull request #403 from CodeYourFuture/js3/week-2
Add JS3 Week 2 prep content MOVED TO SPRINT 3
2 parents 2df672c + 5d0adb3 commit fbce9cf

File tree

15 files changed

+637
-5
lines changed

15 files changed

+637
-5
lines changed
+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// put anything side by side
2+
3+
.c-columns {
4+
display: grid;
5+
gap: var(--theme-spacing--gutter);
6+
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
7+
}
+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
+++
2+
title = '⏳ Asynchrony : outside time'
3+
headless = true
4+
time = 40
5+
facilitation = false
6+
emoji= '🧩'
7+
[objectives]
8+
1="Define asynchrony"
9+
2="Explain why we need asynchrony"
10+
3="Identify an asynchronous method we have already used"
11+
+++
12+
13+
We can handle latency using {{<tooltip title="asynchronous execution">}}run code in a different order.{{</tooltip>}} To understand asynchrony we first need to be clear about {{<tooltip title="synchronous execution">}}run code in the order it is written.{{</tooltip>}}.
14+
15+
We have written a lot of JavaScript programs that execute sequentially. This means that each line of code is run in order, one after the other.
16+
{{<columns>}}
17+
18+
#### For example:
19+
20+
```js
21+
console.log("first");
22+
console.log("second");
23+
console.log("third");
24+
```
25+
26+
<--->
27+
28+
#### Outputs:
29+
30+
```console
31+
first
32+
second
33+
third
34+
```
35+
36+
{{</columns>}}
37+
Each line of code is run in order. This is synchronous execution. We do this because JavaScript is {{<tooltip title="single threaded">}}
38+
A single thread can do one thing at a time. JavaScript is a single threaded language.
39+
{{</tooltip>}}.
40+
41+
When we call a function, the function will run to completion before the next line of code is executed. But what if we need to wait for something to happen? What if we need to wait for our data to arrive before we can show it? In this case, we can use **asynchronous execution**.
42+
43+
{{<tabs name="Event Loop">}}
44+
{{<tab name="Event Listener">}}
45+
We have already used asynchronous execution. We have defined `eventListener`s that _listen_ for events to happen, _then_ execute a callback function. But here's a new idea: eventListeners are part of the [Event API](https://developer.mozilla.org/en-US/docs/Web/API/Event). They are not part of JavaScript! 🤯 This means you can't use them in a Node REPL, but they are implemented in web browsers. The core of JavaScript is the same everywhere, but different contexts may add extra APIs.
46+
47+
When you set an eventListener you are really sending a call to a Web API and asking it do something for you.
48+
49+
```js
50+
const search = document.getElementById("search");
51+
search.addEventListener("input", handleInput);
52+
```
53+
54+
The callback `handleInput` cannot run until the user types. With `fetch`, the callback function cannot run until the data arrives. In both cases, we are waiting for something to happen before we can run our code.
55+
56+
We use a function as a way of wrapping up the code that needs to be run later on. This means we can tell the browser _what_ to do when we're done waiting.
57+
{{</tab>}}
58+
{{<tab name="Visualise the Event Loop">}}
59+
60+
<iframe src="http://latentflip.com/loupe/?code=JC5vbignYnV0dG9uJywgJ2NsaWNrJywgZnVuY3Rpb24gb25DbGljaygpIHsKICAgIGNvbnNvbGUubG9nKCdZb3UgY2xpY2tlZCB0aGUgYnV0dG9uIScpOyAgICAKfSk7Cgpjb25zb2xlLmxvZygiSGkhIik7Cgpjb25zb2xlLmxvZygiV2VsY29tZSB0byB0aGUgZXZlbnQgbG9vcCIpOw%3D%3D!!!PGJ1dHRvbj5DbGljayBtZSE8L2J1dHRvbj4%3D" width="100%" height="480px"></iframe>
61+
{{</tab>}}
62+
{{</tabs>}}
63+
64+
### 🧠 Recap our concept map
65+
66+
```mermaid
67+
graph LR
68+
TimeProblem[🗓️ Time Problem] --> |caused by| SingleThread[🧵 Single thread]
69+
SingleThread --> |send tasks to| ClientAPIs
70+
TimeProblem --> |solved by| Asynchrony[🛎️ Asynchrony]
71+
Asynchrony --> | delivered with | ClientAPIs{💻 Client APIs}
72+
ClientAPIs --> |like| setTimeout[(⏲️ setTimeout)]
73+
ClientAPIs --> |like| eventListener[(🦻🏾 eventListener)]
74+
ClientAPIs --> |like| fetch[(🐕 fetch)]
75+
```
+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
+++
2+
title = '🪃 Callbacks'
3+
headless = true
4+
time = 20
5+
facilitation = false
6+
emoji= '🧩'
7+
[objectives]
8+
1='Define a callback'
9+
2="Sketch the event loop"
10+
3="Predict the order of logged numbers using the event loop model"
11+
+++
12+
13+
Consider this visualisation of an asynchronous program:
14+
15+
<iframe title="code running out of order and off the thread" src="http://latentflip.com/loupe/?code=c2V0VGltZW91dChmdW5jdGlvbiB0aW1lb3V0KCkgewogICAgY29uc29sZS5sb2coIjEiKTsKfSwgMjAwMCk7CnNldFRpbWVvdXQoZnVuY3Rpb24gdGltZW91dCgpIHsKICAgIGNvbnNvbGUubG9nKCIyIik7Cn0sIDUwMCk7CnNldFRpbWVvdXQoZnVuY3Rpb24gdGltZW91dCgpIHsKICAgIGNvbnNvbGUubG9nKCIzIik7Cn0sIDApOwo%3D!!!" width="100%" height="480px"></iframe>
16+
17+
When we call [`setTimeout`](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout) we send **a function call** to a client side Web API. The code isn't executing in our single thread any more, so we can run the next line. The countdown _is_ happening, but it's not happening _in our thread_.
18+
19+
When the time runs out, our Web API sends a message to our program to let us know. This is called an {{<tooltip title="event">}}An event is a signal that something has happened.{{</tooltip>}}. Our API sends its message to our {{<tooltip title="event loop">}}The event loop is a JavaScript mechanism that handles asynchronous callbacks.{{</tooltip>}}. And what message does the event loop send? It sends a **callback**. It sends _our_ call _back_. It tells our thread to run the code in that function.
20+
21+
{{<note type="tip" title="Our call is back">}}
22+
A callback is our function call, sent back to us through the event loop, for us to run.
23+
{{</note>}}
24+
25+
{{<tabs name="Event Loop">}}
26+
{{<tab name="Sketch your mental model">}}
27+
**With a pen and paper**, draw a diagram of your mental model of the event loop.
28+
29+
Use your model to predict the order of logged numbers in the following code snippet:
30+
31+
```js
32+
setTimeout(function timeout() {
33+
console.log("1");
34+
}, 2000);
35+
setTimeout(function timeout() {
36+
console.log("2");
37+
}, 500);
38+
setTimeout(function timeout() {
39+
console.log("3");
40+
}, 0);
41+
```
42+
43+
{{</tab>}}
44+
{{<tab name="Compare your model">}}
45+
46+
```mermaid
47+
graph
48+
Callbacks{{🪃 Callbacks}} --> |run on| SingleThread[🧵 Single thread]
49+
SingleThread --> |handled by| EventLoop[🔁 Event Loop]
50+
EventLoop --> |queues| Callbacks
51+
SingleThread --> |send tasks to| ClientAPIs{💻 Client APIs}
52+
ClientAPIs --> | send| Callbacks
53+
```
54+
55+
Did yours look different? There are many ways to visualise the event loop. Work on building your own mental model that helps you predict how code will run.
56+
{{</tab>}}
57+
{{</tabs>}}
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
+++
2+
title = 'Chaining Promises'
3+
headless = true
4+
time = 20
5+
facilitation = false
6+
emoji= '🧩'
7+
[objectives]
8+
+++

content/en/js3/blocks/fetch/index.md

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
+++
2+
title = 'fetch API'
3+
headless = true
4+
time = 20
5+
facilitation = false
6+
emoji= '🧩'
7+
[objectives]
8+
+++
9+
10+
Let's suppose we have a remote API hosted at the following url: "https://api-film-data.com".
11+
12+
We can use applications like Postman to make requests to APIs. However, we want to make a request for the film data using JavaScript. We can use `fetch` to make network requests in JavaScript. Let's take a look at how we can do this:
13+
14+
```js
15+
const filmData = fetch("https://api-film-data.com/films");
16+
```
17+
18+
`fetch` is a JavaScript function. We call `fetch` using the url of the remote API we wish to fetch data from. Once `fetch` has got the data then we want to store it in a variable so we can then use it in our application. Let's log this data:
19+
20+
```js
21+
const filmData = fetch("https://api-film-data.com/films");
22+
console.log(filmData);
23+
```
24+
25+
However, if we log this variable we don't get an array of data. We get:
26+
27+
```console
28+
Promise <pending>
29+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
+++
2+
title = '🐕 Fetching data'
3+
headless = true
4+
time = 20
5+
facilitation = false
6+
emoji= '🧩'
7+
[objectives]
8+
1='Define a client side Web API'
9+
2='Define a server side API'
10+
+++
11+
12+
So far we have displayed film data stored in our JavaScript code. But real applications fetch data from servers over the internet. We can restate our problem as follows:
13+
14+
> _Given_ an **API that serves** film data
15+
> _When_ the page first loads
16+
> _Then_ the page should `fetch` and display the list of film data, including the film title, times and film certificate
17+
18+
### 💻 Client side and 🌐 Server side APIs
19+
20+
We will use [`fetch()`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch), a {{<tooltip title="client side Web API">}}
21+
A client side [Web API](https://developer.mozilla.org/en-US/docs/Web/API) lives in the browser. They provide programmatic access _to_ built-in browser functions _from_ JavaScript. {{</tooltip>}}. Fetch will fetch our data from the {{<tooltip title="server side API">}}
22+
A server side API lives on a server. They provide programmatic access _to_ data or functions stored on the server _from_ JavaScript. {{</tooltip>}}.
23+
24+
APIs are useful because they let us get information which we don't ourselves know. The information may change over time, and we don't need to update our application. When we ask for the information, the API will tell us the latest version.
25+
26+
We also don't need to know how the API works in order to use it. It may be written in a different programming language. It may talk to other APIs we don't know about. All we need to know is how to talk to it. This is called the **interface**.
27+
28+
_Using_ fetch is simple. But we want to understand what is happening more completely. So let's take ourselves on a journey through time.
29+
30+
<details>
31+
<summary>👉🏾 Unfurl to see the journey (we will explain this in little pieces)</summary>
32+
33+
```mermaid
34+
graph TD
35+
fetch[(🐕 fetch)] --> |sends a| Request{📤 Request}
36+
Request --> |has a latency| TimeProblem[🗓️ Time Problem]
37+
Request --> |to| ServerAPIs
38+
fetch --> |is a| ClientAPIs
39+
40+
TimeProblem --> |caused by| SingleThread[🧵 Single thread]
41+
Callbacks{{🪃 Callbacks}} --> |run on| SingleThread
42+
SingleThread --> |handled by| EventLoop[🔁 Event Loop]
43+
EventLoop --> |queues| Callbacks
44+
SingleThread --> |send tasks to| ClientAPIs
45+
SingleThread --> |handled by| Asynchrony
46+
47+
TimeProblem --> |solved by| Asynchrony[🛎️ Asynchrony]
48+
Asynchrony --> |delivered with| Promise{{🤝 Promises}}
49+
Asynchrony --> | delivered with | ClientAPIs
50+
Promise --> |resolve to a| Response{📤 Response}
51+
Promise --> |join the| EventLoop{{Event Loop 🔁}}
52+
Promise --> |syntax| async{{🏃‍♂️ async}}
53+
async --> |syntax| await{{📭 await}}
54+
await --> |resolves to| Response
55+
Response ---> |sequence with| then{{✔️ then}}
56+
57+
58+
APIs((🧰 APIs)) --> |live in your browser| ClientAPIs{💻 Client side APIs}
59+
ClientAPIs --> |like| setTimeout[(⏲️ setTimeout)]
60+
ClientAPIs --> |like| eventListener[(🦻🏾 eventListener)]
61+
APIs --> |live on the internet| ServerAPIs{🌐 Server side APIs}
62+
ServerAPIs --> |serve our| Data[(💾 Data)]
63+
Data --> |as a| Response
64+
65+
```
66+
67+
😵‍💫 This is a lot to take in. Let's break it down and make sense of it.
68+
69+
</details>
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
+++
2+
title = 'How the internet works'
3+
headless = true
4+
time = 20
5+
facilitation = false
6+
emoji= '🧩'
7+
[objectives]
8+
1='Describe what happens when a user enters a url into a browser'
9+
2='Explain the purpose of the HTTP protocol'
10+
3='Define a GET request in the HTTP protocol'
11+
+++
12+
13+
We've been using the internet for years, but how does it actually work? What happens when you type a URL into a browser? How does the browser know where to go? How does it know what to show? How does it know how to show it?
14+
15+
{{<tabs name="How the internet works playlist">}}
16+
{{<tab name="What is the internet">}}
17+
{{<youtube>}}https://www.youtube.com/watch?v=Dxcc6ycZ73M
18+
{{</youtube>}}
19+
{{</tab>}}
20+
{{<tab name="Understanding networks">}}
21+
{{<youtube>}}https://www.youtube.com/watch?v=ZhEf7e4kopM{{</youtube>}}
22+
{{</tab>}}
23+
{{<tab name="HTTPS & HTML">}}
24+
{{<youtube>}}https://www.youtube.com/watch?v=kBXQZMmiA4s{{</youtube>}}
25+
{{</tab>}}
26+
{{</tabs>}}
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
+++
2+
title = '🗓️ Latency'
3+
headless = true
4+
time = 5
5+
facilitation = false
6+
emoji= '🧩'
7+
[objectives]
8+
1='Define latency'
9+
+++
10+
11+
```mermaid
12+
graph LR
13+
fetch[(🐕 fetch)] --> |sends a| Request{📤 Request}
14+
Request --> |has a latency| TimeProblem[🗓️ Time Problem]
15+
```
16+
17+
Instead of already having our data, we are now sending a request over the network to another computer, and then waiting for that computer to send us a response back. Now that our data is going on a journey over a network, we introduce the problem of **latency**.
18+
19+
Latency is the time taken for a request to traverse the network.
20+
21+
> 💡 Network latency is travel time.
22+
23+
Why is latency a problem? Because it means we need to **wait** for our data. But our program can only do one thing at a time - if we stopped our program to wait for data, then we wouldn't be able to do anything else. We need to handle this time problem.
24+
25+
Programming often involves time problems, and latency is just one of them.
+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
+++
2+
title = '🌐 Requesting from a server side API'
3+
headless = true
4+
time = 20
5+
facilitation = false
6+
emoji= '🧩'
7+
[objectives]
8+
1="List 5 preceding concepts of asynchronous programming in JavaScript"
9+
2="Identify 2 unknown concepts still to be learned"
10+
3="Fetch data from a server side API using a client side Web API"
11+
+++
12+
13+
So now we have these pieces of our giant concept map
14+
15+
1. 📤 we know that we can [send a request](#fetching-data) using `fetch()`
16+
1. 🐕 we know that `fetch` is a [💻 client side 🧰 Web API](#fetching-data)
17+
1. 🗓️ we know that sending 📤 requests over a network takes [time](#latency)
18+
1. 🧵 we know that we should [not stop our program](#asynchrony) to wait for data
19+
1. 🪃 we know that we can [use callbacks](#callbacks) to manage events
20+
21+
But we still don’t know how to use `fetch` to get data from a server side API. Let’s find this out now. In [our filterFilms code](https://curriculum.codeyourfuture.io/filterfilms), replace the films array with data fetched from a server.
22+
23+
```js
24+
// Begin with an empty state
25+
const state = {
26+
films: [],
27+
};
28+
// Data
29+
const endpoint = "//curriculum.codeyourfuture.io/dummy-apis/films.json";
30+
31+
const fetchFilms = async () => {
32+
const response = await fetch(endpoint);
33+
return await response.json();
34+
}; // our async function returns a Promise
35+
36+
fetchFilms().then((films) => {
37+
render(filmContainer, films); // when
38+
});
39+
```
40+
41+
🐕 `fetch` returns a 🫱🏿‍🫲🏽 ‍`Promise`; the 🫱🏿‍🫲🏽 `Promise` fulfils itself with a 📥 response; the response contains our 💾 data.
42+
43+
We will dig into this syntax: `Promises`, `async`, `await`, and `then` in our next sprint and complete our concept map.

content/en/js3/prep/index.md

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ menu_level = ['module']
77
weight = 1
88
backlog= 'Module-JS3'
99
[[blocks]]
10+
name="How the internet works"
11+
src="js3/blocks/internet"
12+
[[blocks]]
1013
name="Technical Writing 101"
1114
src="https://github.com/CodeYourFuture/Module-JS3/issues/243"
1215
+++

content/en/js3/sprints/3/prep/index.md

+15-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,21 @@ menu_level = ['sprint']
66
weight = 1
77
backlog= 'Module-JS3'
88
backlog_filter= 'Week 3'
9-
9+
[[blocks]]
10+
name="Fetching data"
11+
src="js3/blocks/fetching-data"
12+
[[blocks]]
13+
name="Latency"
14+
src="js3/blocks/latency"
15+
[[blocks]]
16+
name="Asynchrony"
17+
src="js3/blocks/asynchrony"
18+
[[blocks]]
19+
name="Callbacks"
20+
src="js3/blocks/callbacks"
21+
[[blocks]]
22+
name="Using .fetch()"
23+
src="js3/blocks/using-fetch"
1024
[[blocks]]
1125
name="Product MVP and features"
1226
src="https://cyf-pd.netlify.app/blocks/define-your-products-mvp/readme/"

layouts/_default/_markup/render-codeblock-mermaid.html.html

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
{{- .Page.Store.Set "hasMermaid" true -}}
21
<style>
32
.mermaid svg {
43
height: initial;
@@ -8,3 +7,6 @@
87
}
98
</style>
109
<pre class="mermaid">{{- .Inner | safeHTML }}</pre>
10+
<script
11+
type="module"
12+
src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.esm.min.mjs"></script>

layouts/partials/scripts.html

-3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,3 @@
88
<script src="{{ $player.Permalink }}" defer></script>
99
{{ $tabs := resources.Get "scripts/tab-panels.js" | resources.Minify }}
1010
<script src="{{ $tabs.Permalink }}" type="module" defer></script>
11-
<script
12-
type="module"
13-
src="https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs"></script>

0 commit comments

Comments
 (0)