Skip to content

Commit 7f41649

Browse files
authored
Merge pull request #1671 from Rnbsov/patch-102
👾 smth
2 parents cec701e + 4d54329 commit 7f41649

File tree

6 files changed

+69
-24
lines changed

6 files changed

+69
-24
lines changed

1-js/02-first-steps/13-while-for/article.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,19 @@
66

77
Для многократного повторения одного участка кода предусмотрены *циклы*.
88

9+
```smart header="Циклы for..of и for..in"
10+
Небольшое объявление для продвинутых читателей.
11+
12+
В этой статье рассматриваются только базывые циклы: `while`, `do..while` и `for(..;..;..)`.
13+
14+
Если вы пришли к этой статье в поисках других типов циклов, вот указатели:
15+
16+
- См. [for..in](info:object#forin) для перебора свойств объекта.
17+
- См. [for..of](info:array#loops) и [Перебираемые объекты](info:iterable) для перебора массивов и перебираемых объектов.
18+
19+
В противном случае, продолжайте читать.
20+
```
21+
922
## Цикл "while"
1023

1124
Цикл `while` имеет следующий синтаксис:

1-js/04-object-basics/01-object/article.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ let user = {
8383
![](object-user-props.svg)
8484

8585
Последнее свойство объекта может заканчиваться запятой:
86+
8687
```js
8788
let user = {
8889
name: "John",
@@ -205,6 +206,7 @@ alert( bag.apple ); // 5, если fruit="apple"
205206
И если посетитель введёт слово `"apple"`, то в объекте `bag` теперь будет лежать свойство `{apple: 5}`.
206207

207208
По сути, пример выше работает так же, как и следующий пример:
209+
208210
```js run
209211
let fruit = prompt("Какой фрукт купить?", "apple");
210212
let bag = {};
@@ -376,7 +378,7 @@ alert( "test" in obj ); // true, свойство существует!
376378
377379
Подобные ситуации случаются очень редко, так как `undefined` обычно явно не присваивается. Для "неизвестных" или "пустых" свойств мы используем значение `null`. Таким образом, оператор `in` является экзотическим гостем в коде.
378380
379-
## Цикл "for..in"
381+
## Цикл "for..in" [#forin]
380382
381383
Для перебора всех свойств объекта используется цикл `for..in`. Этот цикл отличается от изученного ранее цикла `for(;;)`.
382384

1-js/11-async/01-callbacks/article.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11

2-
32
# Введение: колбэки
43

54
Многие действия в JavaScript *асинхронные*.
@@ -54,15 +53,15 @@ newFunction(); // такой функции не существует!
5453
function loadScript(src, *!*callback*/!*) {
5554
let script = document.createElement('script');
5655
script.src = src;
57-
5856
*!*
5957
script.onload = () => callback(script);
6058
*/!*
61-
6259
document.head.append(script);
6360
}
6461
```
6562

63+
Событие `onload` описано в статье <info:onload-onerror#loading-a-script>, оно в основном выполняет функцию после загрузки и выполнения скрипта.
64+
6665
Теперь, если мы хотим вызвать функцию из скрипта, нужно делать это в колбэке:
6766

6867
```js

1-js/11-async/02-promise-basics/article.md

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
# Промисы
23

34
Представьте, что вы известный певец, которого фанаты постоянно донимают расспросами о предстоящем сингле.
@@ -126,9 +127,9 @@ let promise = new Promise(function(resolve, reject) {
126127
Свойства `state` и `result` - это внутренние свойства объекта `Promise` и мы не имеем к ним прямого доступа. Для обработки результата следует использовать методы `.then`/`.catch`/`.finally`, про них речь пойдёт дальше.
127128
```
128129
129-
## Потребители: then, catch, finally
130+
## Потребители: then, catch
130131
131-
Объект `Promise` служит связующим звеном между исполнителем ("создающим" кодом или "певцом") и функциями-потребителями ("фанатами"), которые получат либо результат, либо ошибку. Функции-потребители могут быть зарегистрированы (подписаны) с помощью методов `.then`, `.catch` и `.finally`.
132+
Объект `Promise` служит связующим звеном между исполнителем ("создающим" кодом или "певцом") и функциями-потребителями ("фанатами"), которые получат либо результат, либо ошибку. Функции-потребители могут быть зарегистрированы (подписаны) с помощью методов `.then` и `.catch`.
132133
133134
### then
134135
@@ -210,59 +211,84 @@ promise.catch(alert); // выведет "Error: Ошибка!" спустя од
210211
211212
Вызов `.catch(f)` - это сокращённый, "укороченный" вариант `.then(null, f)`.
212213
213-
### finally
214+
## Очистка: finally
214215
215216
По аналогии с блоком `finally` из обычного `try {...} catch {...}`, у промисов также есть метод `finally`.
216217
217218
Вызов `.finally(f)` похож на `.then(f, f)`, в том смысле, что `f` выполнится в любом случае, когда промис завершится: успешно или с ошибкой.
218219
219-
`finally` хорошо подходит для очистки, например остановки индикатора загрузки, его ведь нужно остановить вне зависимости от результата.
220+
Идея `finally` состоит в том, чтобы настроить обработчик для выполнения очистки/доведения после завершения предыдущих операций.
221+
222+
Например, остановка индикаторов загрузки, закрытие больше не нужных соединений и т.д.
220223
221-
Например:
224+
Думайте об этом как о завершении вечеринки. Независимо от того, была ли вечеринка хорошей или плохой, сколько на ней было друзей, нам все равно нужно (или, по крайней мере, мы должны) сделать уборку после нее.
225+
226+
Код может выглядеть следующим образом:
222227
223228
```js
224229
new Promise((resolve, reject) => {
225-
/* сделать что-то, что займёт время, и после вызвать resolve/reject */
230+
/* сделать что-то, что займёт время, и после вызвать resolve или может reject */
226231
})
227232
*!*
228233
// выполнится, когда промис завершится, независимо от того, успешно или нет
229234
.finally(() => остановить индикатор загрузки)
235+
// таким образом, индикатор загрузки всегда останавливается, прежде чем мы продолжим
230236
*/!*
231237
.then(result => показать результат, err => показать ошибку)
232238
```
233239
234-
Но это не совсем псевдоним `then(f,f)`, как можно было подумать. Существует несколько важных отличий:
240+
Обратите внимание, что `finally(f)` - это не совсем псевдоним `then(f,f)`, как можно было подумать.
241+
242+
Есть важные различия:
235243
236244
1. Обработчик, вызываемый из `finally`, не имеет аргументов. В `finally` мы не знаем, как был завершён промис. И это нормально, потому что обычно наша задача - выполнить "общие" завершающие процедуры.
245+
246+
Пожалуйста, взгляните на приведенный выше пример: как вы можете видеть, обработчик `finally` не имеет аргументов, а результат promise обрабатывается в следующем обработчике.
247+
237248
2. Обработчик `finally` "пропускает" результат или ошибку дальше, к последующим обработчикам.
238249
239250
Например, здесь результат проходит через `finally` к `then`:
251+
240252
```js run
241253
new Promise((resolve, reject) => {
242-
setTimeout(() => resolve("result"), 2000)
254+
setTimeout(() => resolve("value"), 2000);
243255
})
244-
.finally(() => alert("Промис завершён"))
245-
.then(result => alert(result)); // <-- .then обработает результат
256+
.finally(() => alert("Промис завершён")) // срабатывает первым
257+
.then(result => alert(result)); // <-- .then показывает "value"
246258
```
247-
259+
260+
Как вы можете видеть, значение возвращаемое первым промисом, передается через `finally` к следующему `then`.
261+
262+
Это очень удобно, потому что `finally` не предназначен для обработки результата промиса. Как уже было сказано, это место для проведения общей очистки, независимо от того, каков был результат.
263+
248264
А здесь ошибка из промиса проходит через `finally` к `catch`:
249265
250266
```js run
251267
new Promise((resolve, reject) => {
252268
throw new Error("error");
253269
})
254-
.finally(() => alert("Промис завершён"))
255-
.catch(err => alert(err)); // <-- .catch обработает объект ошибки
270+
.finally(() => alert("Промис завершён")) // срабатывает первым
271+
.catch(err => alert(err)); // <-- .catch показывает ошибку
256272
```
257273
258-
Это очень удобно, потому что `finally` не предназначен для обработки результата промиса. Так что он просто пропускает его через себя дальше.
274+
3. Обработчик `finally` также не должен ничего возвращать. Если это так, то возвращаемое значение молча игнорируется.
259275
260-
Мы более подробно поговорим о создании цепочек промисов и передаче результатов между обработчиками в следующей главе.
276+
Единственным исключением из этого правила является случай, когда обработчик `finally` выдает ошибку. Затем эта ошибка передается следующему обработчику вместо любого предыдущего результата.
277+
278+
Подведем итог:
261279
262-
3. Последнее, но не менее значимое: вызов `.finally(f)` удобнее, чем `.then(f, f)` - не надо дублировать функции f.
280+
- Обработчик `finally` не получает результат предыдущего обработчика (у него нет аргументов). Вместо этого этот результат передается следующему подходящему обработчику.
281+
- Если обработчик `finally` возвращает что-то, это игнорируется.
282+
- Когда `finally` выдает ошибку, выполнение переходит к ближайшему обработчику ошибок.
283+
284+
Эти функции полезны и заставляют все работать правильно, если мы используем `finally` так, как предполагается: для общих процедур очистки.
263285
264286
````smart header="На завершённых промисах обработчики запускаются сразу"
265-
Если промис в состоянии ожидания, обработчики в `.then/catch/finally` будут ждать его. Однако, если промис уже завершён, то обработчики выполнятся сразу:
287+
Если промис в состоянии ожидания, обработчики в `.then/catch/finally` будут ждать его.
288+
289+
Иногда может случиться так, что промис уже выполнен, когда мы добавляем к нему обработчик.
290+
291+
В таком случае эти обработчики просто запускаются немедленно:
266292
267293
```js run
268294
// при создании промиса он сразу переводится в состояние "успешно завершён"
@@ -272,10 +298,10 @@ promise.then(alert); // готово! (выведется сразу)
272298
```
273299
````
274300

275-
Теперь рассмотрим несколько практических примеров того, как промисы могут облегчить нам написание асинхронного кода.
276-
277301
## Пример: loadScript [#loadscript]
278302

303+
Теперь рассмотрим несколько практических примеров того, как промисы могут облегчить нам написание асинхронного кода.
304+
279305
У нас есть функция `loadScript` для загрузки скрипта из предыдущей главы.
280306

281307
Давайте вспомним, как выглядел вариант с колбэками:

1-js/11-async/04-promise-error-handling/article.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ new Promise(function() {
199199
## Итого
200200

201201
- `.catch` перехватывает все виды ошибок в промисах: будь то вызов `reject()` или ошибка, брошенная в обработчике при помощи `throw`.
202+
- `.then` также перехватывает ошибки таким же образом, если задан второй аргумент (который является обработчиком ошибок).
202203
- Необходимо размещать `.catch` там, где мы хотим обработать ошибки и знаем, как это сделать. Обработчик может проанализировать ошибку (могут быть полезны пользовательские классы ошибок) и пробросить её, если ничего не знает о ней (возможно, это программная ошибка).
203204
- Можно и совсем не использовать `.catch`, если нет нормального способа восстановиться после ошибки.
204205
- В любом случае нам следует использовать обработчик события `unhandledrejection` (для браузеров и аналог для других окружений), чтобы отслеживать необработанные ошибки и информировать о них пользователя (и, возможно, наш сервер), благодаря чему наше приложение никогда не будет "просто умирать".

2-ui/4-forms-controls/2-focus-blur/article.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
# Фокусировка: focus/blur
23

34
Элемент получает фокус, когда пользователь кликает по нему или использует клавишу `key:Tab`. Также существует HTML-атрибут `autofocus`, который устанавливает фокус на элемент, когда страница загружается. Есть и другие способы получения фокуса, о них - далее.
@@ -51,7 +52,6 @@
5152

5253
Современный HTML позволяет делать валидацию с помощью атрибутов `required`, `pattern` и т.д. Иногда - это всё, что нам нужно. JavaScript можно использовать, когда мы хотим больше гибкости. А ещё мы могли бы отправлять изменённое значение на сервер, если оно правильное.
5354

54-
5555
## Методы focus/blur
5656

5757
Методы `elem.focus()` и `elem.blur()` устанавливают/снимают фокус.
@@ -90,6 +90,8 @@
9090

9191
Отметим, что мы не можем "отменить потерю фокуса", вызвав `event.preventDefault()` в обработчике `onblur` потому, что `onblur` срабатывает *после* потери фокуса элементом.
9292

93+
Однако на практике следует хорошо подумать, прежде чем внедрять что-то подобное, потому что мы обычно *должны показывать ошибки* пользователю, но они *не должны мешать* пользователю при заполнении нашей формы. Ведь, вполне возможно, что он захочет сначала заполнить другие поля.
94+
9395
```warn header="Потеря фокуса, вызванная JavaScript"
9496
Потеря фокуса может произойти по множеству причин.
9597
@@ -102,6 +104,7 @@
102104
103105
Используя эти события, нужно быть осторожным. Если мы хотим отследить потерю фокуса, которую инициировал пользователь, тогда нам следует избегать её самим.
104106
```
107+
105108
## Включаем фокусировку на любом элементе: tabindex
106109

107110
Многие элементы по умолчанию не поддерживают фокусировку.
@@ -125,6 +128,7 @@
125128
- `tabindex="0"` ставит элемент в один ряд с элементами без `tabindex`. То есть, при переключении такие элементы будут после элементов с `tabindex ≥ 1`.
126129

127130
Обычно используется, чтобы включить фокусировку на элементе, но не менять порядок переключения. Чтобы элемент мог участвовать в форме наравне с обычными `<input>`.
131+
128132
- `tabindex="-1"` позволяет фокусироваться на элементе только программно. Клавиша `key:Tab` проигнорирует такой элемент, но метод `elem.focus()` будет действовать.
129133

130134
Например, список ниже. Кликните первый пункт в списке и нажмите `key:Tab`:

0 commit comments

Comments
 (0)