Skip to content

Commit 4d48249

Browse files
authored
Merge pull request #1 from vovachebr/master
Add lesson 16 and lesson 17
2 parents b91821e + cfc9aa8 commit 4d48249

2 files changed

Lines changed: 552 additions & 0 deletions

File tree

lessons/lesson16/lesson.md

Lines changed: 334 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,335 @@
11
# Lesson 16
2+
3+
---
4+
5+
title: Занятие 16
6+
description: Базовое использование API и JavaScript. Как работать с сетевыми ресурсами
7+
8+
---
9+
10+
# OTUS
11+
12+
## Javascript Basic
13+
14+
<!--v-->
15+
16+
### Вопросы?
17+
18+
<!--s-->
19+
20+
### Базовое использование API и JavaScript.
21+
22+
#### Как работать с сетевыми ресурсами
23+
24+
<!-- s -->
25+
26+
### Асинхронный код - минимум для работы
27+
28+
_Подробнее будет в третьем модуле на занятии про асинхронный код_
29+
30+
<!-- v -->
31+
32+
#### JS - ОДНОПОТОЧНЫЙ ЯЗЫК
33+
34+
- Отрисовка DOM
35+
- Обработка пользовательского ввода
36+
- Выполнение JS кода
37+
38+
<!-- v -->
39+
40+
#### [ОЧЕРЕДЬ ЗАДАЧ В JS](https://developer.mozilla.org/ru/docs/Web/JavaScript/EventLoop)
41+
42+
- Среда выполнения содержит очередь событий (список событий, подлежащих обработке)
43+
- Каждое событие ассоциируется с некоторой функцией.
44+
- Каждый вызов функции добавляет запись в стек
45+
- При завершении функции запись изымается из стека
46+
- Когда стек освобождается, событие извлекается из очереди и обрабатывается (функция вызывается).
47+
48+
<!-- v -->
49+
50+
На бытовом уровне мы могли бы это объяснить так...
51+
52+
<!-- v -->
53+
54+
[Демонстрация](https://codesandbox.io/s/github/vvscode/otus--javascript-basic/tree/lesson04/lessons/lesson04/code/singleThreadInJs?file=/index.html)
55+
56+
<!-- v -->
57+
58+
Поэтому операции, которые занимают длительное (больше 50 ms) операции стараются
59+
60+
- переложить на внешнего исполнителя
61+
- отложить исполнение и разбить на части
62+
63+
<!-- v -->
64+
65+
Так появляется **асинхронный код** - когда результат вы получаете не немедленно, а отложено во времени.
66+
67+
<!-- v -->
68+
69+
Как работать с таким асинхронным кодом? Как это выглядит?
70+
71+
<!-- v -->
72+
73+
```js [1-30]
74+
// работа с callback-функциями
75+
const x = 2;
76+
// результат мы можем обработать в callback-функции
77+
calculateSomethingAsyncWithCallback(x, (result) => {
78+
console.log(result);
79+
});
80+
// в node.js было принято
81+
calculateSomethingAsyncWithCallback(x, (error, result) => {
82+
if (error) {
83+
return console.error(error);
84+
}
85+
// ...
86+
});
87+
```
88+
89+
<!-- v -->
90+
91+
```js [1-30]
92+
// работа с callback-функциями
93+
const x = 2;
94+
calculateSomethingAsyncWithCallback(x, (result) => {
95+
calculateSomethingElseAsyncWithCallback(result, (secondResult) => {
96+
console.log(result);
97+
});
98+
});
99+
```
100+
101+
<!-- v -->
102+
103+
### Вопросы?
104+
105+
<!-- v -->
106+
107+
Для решения проблемы [callback hell](http://callbackhell.com/) ввели интерфейс [Promise](https://developer.mozilla.org/ru/docs/Web/JavaScript/Guide/Ispolzovanie_promisov).
108+
109+
<!-- v -->
110+
111+
```js [1-30]
112+
function doSomething() {
113+
return new Promise((resolve, reject) => {
114+
console.log("Готово.");
115+
// Успех в половине случаев.
116+
if (Math.random() > 0.5) {
117+
resolve("Успех");
118+
} else {
119+
reject("Ошибка");
120+
}
121+
});
122+
}
123+
124+
const promise = doSomething();
125+
promise.then(successCallback, failureCallback);
126+
promise.then(successCallback).catch(failureCallback);
127+
```
128+
129+
<!-- v -->
130+
131+
```js [1-30]
132+
calculateSomethingAsyncWithPromise(x)
133+
.then((result) => calculateSomethingElseAsyncWithPromise(result))
134+
.then((secondResult) => console.log(secondResult));
135+
```
136+
137+
<!-- v -->
138+
139+
### Вопросы?
140+
141+
<!-- v -->
142+
143+
Но в Javascript приходит все больше и больше людей с других языков, и им непривычно читать такой код. Кроме того он имеет некоторые проблемы (например нам нужен одновременный доступ к `result` и `secondResult`).
144+
145+
<!-- v -->
146+
147+
Появились `async` функции. Которые предоставляют [`await` механизм](https://learn.javascript.ru/async-await).
148+
149+
<!-- v -->
150+
151+
Мы можем пометить функцию ключевым словом async. Это дает следующее:
152+
153+
1. функция теперь неявно возвращает Promise
154+
155+
1. внутри функции мы можем использовать ключевое слово `await` для разворачивания Promise-результатов
156+
157+
<!-- v -->
158+
159+
```js [1-30]
160+
(async function () {
161+
const x = 2;
162+
const result = await calculateSomethingAsyncWithPromise(x);
163+
const secondResult = await calculateSomethingElseAsyncWithPromise(result);
164+
console.log(secondResult);
165+
})();
166+
```
167+
168+
<!-- v -->
169+
170+
[Top-level await](https://github.com/tc39/proposal-top-level-await).
171+
172+
```js [1-30]
173+
const x = 2;
174+
const result = await calculateSomethingAsyncWithPromise(x);
175+
const secondResult = await calculateSomethingElseAsyncWithPromise(result);
176+
console.log(secondResult);
177+
```
178+
179+
<!-- v -->
180+
181+
Краткий итог:
182+
183+
- некоторый функции нужно вызывать с ключевым словом `await`
184+
- `await` работает только внутри функций, которые помечены как `async` и в top-level
185+
186+
Подробнее мы будем разбирать на занятии про асинхронность
187+
188+
<!-- v -->
189+
190+
### Вопросы?
191+
192+
<!-- v -->
193+
194+
В разработке принято писать на уровне интерфейсов (абстракций), а не реализаций. То есть вы должны знать ЧТО делает функция или модуль, но не КАК.
195+
196+
Когда вы начинаете использовать детали реализации - это называется "протекающая абстракция".
197+
198+
<!-- v -->
199+
200+
Типичные кандидаты на асинхронные операции:
201+
202+
- запрос данных от пользователя
203+
- сохранение и чтение данных
204+
- обращение к стороннему сервису
205+
- валидации и сложные вычисления
206+
207+
<!-- v -->
208+
209+
Но при этом
210+
211+
- для запроса данных от пользователя есть синхронные `alert` / `prompt`
212+
- для чтения и сохранения данных есть синхронный `localStorage`
213+
214+
<!-- v -->
215+
216+
Лучше сразу заложить возможность для расширения, и использовать асинхронные обертки. Тогда в любой момент можно будет поменять реализацию, и вместо `localStorage` сохранять данные на сервере, например. А вместо `alert` показывать красивое стилизованное модальное окно (которое не блокирует поток).
217+
218+
<!-- v -->
219+
220+
```js [1-30]
221+
async function asyncPrompt(request) {
222+
return prompt(request);
223+
}
224+
// const x = asyncPrompt(); работать не будет
225+
const x = await asyncPrompt();
226+
```
227+
228+
<!-- v -->
229+
230+
### Вопросы?
231+
232+
<!-- s -->
233+
234+
### [Работа со сторонними сервисами](https://learn.javascript.ru/network)
235+
236+
<!-- v -->
237+
238+
Для работы с HTTP запросами у нас есть два варианта (на самом деле больше, если подключать библиотеки):
239+
240+
- [XMLHttpRequest](https://learn.javascript.ru/xmlhttprequest)
241+
- [fetch](https://learn.javascript.ru/fetch)
242+
243+
<!-- v -->
244+
245+
`fetch` - поддерживается современными браузерами, предоставляет Promise-based интерфейс (удобен для `async` функций) и прост в использовании.
246+
247+
<!-- v -->
248+
249+
```js [1-30]
250+
// await-friendly окружение
251+
let response = await fetch(url);
252+
253+
let text = await response.text();
254+
255+
console.log(text);
256+
```
257+
258+
<!-- v -->
259+
260+
```js [1-30]
261+
// await-friendly окружение
262+
let response = await fetch("https://jsonplaceholder.typicode.com/users");
263+
264+
let jsonData = await response.json();
265+
console.log(jsonData);
266+
```
267+
268+
<!-- v -->
269+
270+
`fetch` возвращает вам объект типа [`Response`](https://developer.mozilla.org/ru/docs/Web/API/Response).
271+
272+
Чаще всего используются
273+
274+
- поле `ok`
275+
- поле `status`
276+
- методы `text()` и `json()`
277+
278+
<!-- v -->
279+
280+
### Вопросы?
281+
282+
<!-- v -->
283+
284+
[Практика](https://codesandbox.io/s/github/vvscode/otus--javascript-basic/tree/lesson04/lessons/lesson04/code/fetchPractice)
285+
286+
[OpenWeather API](https://openweathermap.org/current)
287+
288+
<!-- v -->
289+
290+
### Вопросы?
291+
292+
<!-- v -->
293+
294+
Дополнительное задание:
295+
296+
при заходе на страницу показать пользователю погоду в его городе. Для получения этой информации можно сделать запрос на `https://get.geojs.io/v1/ip/geo.json`, который вернет данные в формате JSON.
297+
298+
[GeoAPI](https://www.geojs.io/docs/v1/endpoints/geo/)
299+
300+
<!-- s -->
301+
302+
Если вы хотите собрать все вместе, можете выполнить следующий проект (его уже можно показывать друзьям).
303+
304+
[Сайт с прогонозом погоды](https://github.com/vvscode/otus--javascript-basic/blob/master/lessons/lesson09/homework.md)
305+
306+
Само домашнее задание у вас будет позже, но уже сейчас вы можете выполнять часть, связанную со страницей.
307+
308+
<!-- v -->
309+
310+
### Вопросы?
311+
312+
<!-- s -->
313+
314+
#### Дополнительные материалы
315+
316+
<!-- v -->
317+
318+
1. [Путеводитель по JavaScript Promise для новичков](https://habr.com/ru/company/zerotech/blog/317256/)
319+
2. [Public APIs](https://github.com/public-apis/public-apis#open-source-projects)
320+
3. [JavaScript. Как работать с API Telegram, Youtube и VK](https://live.ithillel.ua/javascript.-rabota-s-api)
321+
4. [Что на самом деле происходит, когда пользователь вбивает в браузер адрес google.com](https://habr.com/ru/company/htmlacademy/blog/254825/)
322+
323+
<!-- v -->
324+
325+
#### Вопросы для самопроверки
326+
327+
1. Что такое CORS?
328+
329+
2. Что такое и какие есть коды ответов HTTP?
330+
331+
3. Что такое jsonp-запрос?
332+
333+
4. Быть в состоянии рассказать что такое XHR, AJAX, CDN
334+
335+
5. Чем XMLHTTPRequest отличается от fetch?

0 commit comments

Comments
 (0)