Skip to content

Commit f1748e5

Browse files
committed
i18n-rus: add russian
1 parent e3675b9 commit f1748e5

File tree

10 files changed

+367
-2
lines changed

10 files changed

+367
-2
lines changed

exercises/catch_error/problem.ru.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
Обработка ошибок и генераторы.
2+
3+
## Теория
4+
Лучшее, что генераторы принесли нам это **синхронность**. Код внутри генераторов
5+
является синхронным, даже еслимы вызываем генератор в асинхронном режиме.
6+
7+
Это означает, что мы можем использовать конструкцию `try {...} catch () {}` с легкостью.
8+
9+
```js
10+
function *dummy () {
11+
try {
12+
null.foo(); // вызываем exception
13+
} catch (e) {
14+
console.log('Caught exception: %s', e);
15+
}
16+
yield 'Попали сюда без сбоев';
17+
}
18+
dummy().next();
19+
// Caught exception: TypeError: Cannot read property 'foo' of null
20+
{ value: 'Попали сюда без сбоев', done: false }
21+
```
22+
Также, функция-генератор имеет `throw()` метод, который позволяет отправить
23+
исключение внутрь функции, позволяя конструкции `try-catch` отловить исключение
24+
внутри генератора.
25+
26+
Помните: если внутри генератора нет конструкции `try-catch`, то послыаемое
27+
исключение будет просто возвращено из функции.
28+
29+
```js
30+
function *foo () { yield 'inside foo'; }
31+
32+
var it = foo();
33+
try {
34+
it.throw('BOOO from outside');
35+
} catch (errFromIt) {
36+
console.log('Error: %s ', errFromIt); // Error: BOOO from outside
37+
}
38+
```
39+
40+
## Задание
41+
Реализуйте функцию-генератор `upper`, которая принимает массив строк
42+
на вход и вызвращает каждую строк в верхнем регистре.
43+
44+
**Проблема:** кто-то послал число в `upper` и это сломало всю работу.
45+
Пожалуйста исправьте это. Если `upper` получил число, то он должен вернуть `null`.
46+
47+
**Шаблон решения:**
48+
49+
```js
50+
function *upper (items) {
51+
// ваш код здесь
52+
}
53+
54+
var bad_items = ['a', 'B', 1, 'c'];
55+
56+
for (var item of upper(bad_items)) {
57+
console.log(item);
58+
}
59+
// вывод: A, B, null, C
60+
```
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
Генераторы внутри генераторов.
2+
3+
## Теория
4+
Мы можем передавать управление процессом итерации от нашего генератора
5+
к другому. В этом нам поможет выражение `yield * expression`, `*` означает,
6+
что **expression** является генератором и мы можем передать ему управление.
7+
8+
```js
9+
function *foo() {
10+
yield 2;
11+
yield 3;
12+
}
13+
14+
function *main() {
15+
yield 1;
16+
yield *foo(); // передаем управление
17+
}
18+
19+
for (var v of main()) {
20+
console.log( v );
21+
}
22+
// 1 2 3
23+
```
24+
25+
## Справка
26+
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield*
27+
28+
## Задача
29+
Реализуйте функцию-генератор `flat` принимает вложенный массив и выравнивает его.
30+
31+
**Шаблон решения:**
32+
33+
```js
34+
function *flat (arr) {
35+
// ваш код здесь
36+
}
37+
38+
var A = [1, [2, [3, 4], 5], 6];
39+
for (var f of flat(A)) {
40+
console.log( f );
41+
}
42+
// 1 2 3 4 5 6
43+
```
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
Генераторы и итераторы. В чем разница?
2+
3+
## Теория
4+
Главное, что необходимо понимать, это то, что __генераторы это итераторы__.
5+
Генераторы являются простой оберткой объекта итератора (см `iterator protocol` ниже).
6+
7+
Генераторы не исполняются в свой первый вызов, вместо этого они возврщают
8+
объект итератора с несколькими дополнительными функциями (`send, next, throw, close`).
9+
10+
Итератор - это шаблон проектирования, где мы проходимся по последовательности элементов
11+
по одному на итерацию с помощью вызова `next()`. На каждый вызов `next()` мы получаем
12+
следующий элемент из последовательности :)
13+
Звучит вполне логично и уже знакомо для нас.
14+
15+
## Справка
16+
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/The_Iterator_protocol
17+
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of
18+
- http://wiki.ecmascript.org/doku.php?id=harmony:iterators
19+
20+
## Задание
21+
22+
Реализуйте функцию-генератор `factorial` которая на вход получает число **n**
23+
и начиная с **1** итеративно выводит факториал каждого числа до **n** включительно.
24+
25+
Не используйте рекурсию. Используйте цикл.
26+
27+
**Шаблон решения:**
28+
```js
29+
function *factorial(n){
30+
// ваш код здесь
31+
}
32+
33+
for (var n of factorial(5)) {
34+
console.log(n)
35+
}
36+
// 1, 2, 6, 24, 120
37+
```
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
Look sync. Do async.
2+
3+
## Теория
4+
Генераторы позволяют нам скрыть **асинхронность** как деталь реализации
5+
и писать легкий для чтения, поддерживаемый, синхронно-выглядящий код.
6+
7+
Чего-чего?
8+
9+
Генераторы могут **приостановить их выполнение** до тех пор, пока
10+
асинхронные вызовы не завершат свое выполенение.
11+
12+
Например, вы хотите прочитать текущий каталог c помощью `fs.readdir(dir, cb)`
13+
без падения в callback-страну.
14+
15+
```js
16+
var fs = require('fs');
17+
18+
function run (generator) {
19+
var it = generator(go);
20+
21+
function go (err, result) {
22+
it.next(result);
23+
}
24+
25+
go();
26+
}
27+
28+
run(function* (done) {
29+
// читаем `learn-generators` директорию exercises
30+
var exercises = yield fs.readdir('exercises', done);
31+
console.log(exercises); // [ 'look_sync_do_async', ..., 'run_stop_run' ]
32+
});
33+
34+
```
35+
Здесь мы создали генератор, который остановил свое выполнение, подождал
36+
пока функция `readdir` завершит свое выполнение и вернет результат.
37+
38+
Ключевым элементом в этом примере является функция `run`. Что она делает:
39+
40+
**1)** создает оновый бъект генератор (`it`);
41+
**2)** определяем функцию `go`, которая вызывает `it.next`;
42+
**3)** передаем функцию `go` внутрь объекта-генератора;
43+
**4)** вызываем `go` для того чтобы стартовать генератор.
44+
45+
Всего функция `go` будет вызвана дважды, один раз без аргументов (это запустит
46+
исполнение генератора) и второй раз с результатом вызова `fs`, который нам вернет `yield`.
47+
48+
Если сложно уловить мысль, советуем вставить `console.log` внутри функции
49+
и отследить последовательность вызовов программы.
50+
51+
## Справка
52+
- http://nodejs.org/api/fs.html#fs_fs_readdir_path_callback
53+
- http://en.wikipedia.org/wiki/Thunk
54+
55+
## Задание
56+
Добавьте обработку ошибку в данный шаблон. Научите `run` выбрасывать исключение
57+
и отлавливать его в функции-генераторе. `firstFile` должен быть равен `null`,
58+
если он не существует.
59+
60+
**Шаблон решения:**
61+
62+
```js
63+
var fs = require('fs');
64+
65+
function run (generator) {
66+
// см `run` выше
67+
}
68+
69+
run(function* (done) {
70+
// исключение
71+
var dirFiles = yield fs.readdir('NoNoNoNo', done); // нет такой директории
72+
var firstFile = dirFiles[0]; // TypeError: Cannot read property '0' of undefined
73+
74+
console.log(firstFile);
75+
});
76+
```
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
Look sync. Make a promise.
2+
3+
## Теория
4+
Есть еще один путь писать `синхронно-выглядящий` код - это **Promises**.
5+
6+
Так же, как и **callbacks** в предыдущем задании, мы можем подождать, пока
7+
promise вернет результат и вернуть его из генератора.
8+
9+
Давайте попробуем реализовать пример из предыдущего задания - прочитаем
10+
директорию **exercise**, но уже с использованием promise.
11+
12+
```js
13+
var fs = require('fs');
14+
15+
function readDir(dir) {
16+
return new Promise(function (resolve, reject) {
17+
fs.readdir(dir, function (err, res) {
18+
if (err) {
19+
reject(err);
20+
} else {
21+
resolve(res);
22+
}
23+
});
24+
});
25+
}
26+
27+
run(function* () {
28+
// практически та же самая функция-генератор
29+
var exercises = yield readDir('exercises');
30+
console.log(exercises); // [ 'look_sync_do_async', ..., 'run_stop_run' ]
31+
});
32+
33+
```
34+
В этом примере мы определили функцию `readDir` которая возвращает promise с
35+
содержимым переданной ей директории. Но самая интересная часть происходит в
36+
функции `run`, где мы подождали исполнение **`readDir` promise**, получили результат
37+
и продолжили работу.
38+
39+
Каким образом `run` сделала это? Это и есть ваше задание.
40+
41+
## Справка
42+
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
43+
- https://www.promisejs.org/
44+
45+
## Задание
46+
47+
Реализуйте функцию `run`, которая принимает функцию-генератор в качестве аргумента,
48+
запускает ее и возвращает **результат promise** `foo`. Используйте `run` из
49+
предыдущего задания в качестве примера.
50+
51+
**Шаблон решения:**
52+
```js
53+
function askFoo () {
54+
return new Promise(function (resolve, reject) {
55+
resolve('foo');
56+
});
57+
}
58+
59+
function run (generator) {
60+
// ваш код здесь
61+
}
62+
63+
run(function* () {
64+
// обработка ошибок?
65+
var foo = yield askFoo();
66+
console.log(foo);
67+
});
68+
```

exercises/run_stop_run/problem.ru.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
Введение в ES6 генераторы.
2+
3+
## Теория
4+
Генераторы - это функции, которые могут быть остановленны и запущены
5+
в процессе выполнения столько раз, сколько необходимо. Например:
6+
7+
```js
8+
function *foo () {
9+
var stop = yield 'woo';
10+
console.log(stop, 'inside foo')
11+
}
12+
var G = foo();
13+
14+
console.log( G.next() );
15+
// { value: 'woo', done: false }
16+
console.log( G.next('bar') );
17+
// 'bar', 'inside foo'
18+
// { value: undefined, done: true }
19+
```
20+
21+
Что здесь произошло? Можно заменить несколько незнакомых вещей, которые важно отметить:
22+
23+
**1)** `*` - знак того, что `foo` является генератором. Вы можете поставить его
24+
в любое место между `function` и именем функции, не имеет значения куда именно.
25+
26+
**2)** Выражение `yield` - останавливает генератор и отправляет строку `woo`.
27+
Это приостанавливает состояние генератора, пока мы не вызовем `next` (см **3)** ниже).
28+
Мы перезапускаем генератор, посылая строку `bar` в `foo`, которая станет возвращаемым
29+
значением выражения `yield` внутри `foo` (и будет присвоена к `stop`).
30+
31+
**3)** функция `foo` имеет метод `next` который возвращает объект вида:
32+
`{value: VALUE_FROM_YIELD, done: IS_THIS_FINISHED}`.
33+
34+
## Справка
35+
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*
36+
- http://wiki.ecmascript.org/doku.php?id=harmony:generators
37+
38+
## Задание
39+
40+
Реализуйте функцию-генератор `range`, которая принимает аргументы **from** и **to**.
41+
42+
Выведите числа в заданом диапазоне, по одному на каждой итерации.
43+
44+
**Шаблон решения:**
45+
46+
```js
47+
function *range(from, to) {
48+
// ваш код здесь
49+
}
50+
51+
for (var r of range(5, 10)) {
52+
console.log( r );
53+
}
54+
// вывод: 5, 6, 7, 8, 9, 10
55+
```

i18n/credits/ru.footer.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
{yellow}{bold}Rod Vagg (@rvagg){/yellow}{/bold} автор workshopper фреймворка (⌐■_■)

i18n/credits/ru.header.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{yellow}{bold}Воркшоппер создан благодаря усилиям следующих людей:{/bold}{/yellow}
2+
3+
{bold}Name GitHub Twitter{/bold}
4+
-----------------------------------------------------

i18n/ru.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"title": "Изучаем Генераторы",
3+
"subtitle": "Серия практических заданий по изучению ES6 генераторов",
4+
"menu": {
5+
"credits": "БЛАГОДАРНОСТЬ",
6+
"completed": "DONE"
7+
},
8+
"error": {
9+
"didnt_use_generators": "Кажется Вы не использовали генераторы в своем решении (ಠ_ಠ)",
10+
"has_generators": "{red}Для работы с генераторами Вам необходимо установить nodejs >= 0.11.x or iojs >= {/red}\n\nВозможно, для этого вам понадобится:\n {bold}nvm{/bold} https://github.com/creationix/nvm\n {bold}n{/bold} https://github.com/tj/n"
11+
},
12+
"exercise": {
13+
"RUN STOP RUN": "RUN STOP RUN",
14+
"GENERATOR ITERATOR": "GENERATOR ITERATOR",
15+
"DELEGATING GENERATORS": "DELEGATING GENERATORS",
16+
"CATCH ERROR!": "CATCH ERROR!",
17+
"LOOK SYNC. DO ASYNC.": "LOOK SYNC. DO ASYNC.",
18+
"LOOK SYNC. MAKE PROMISE.": "LOOK SYNC. MAKE PROMISE."
19+
}
20+
}

learn-generators.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ function fpath (f) {
99
return path.join(__dirname, f)
1010
}
1111

12-
var learnGenerators = workshopper({
12+
const learnGenerators = workshopper({
1313
name : 'learn-generators',
1414
appDir : __dirname,
15-
languages : ['en', 'fr', 'ko'],
15+
languages : ['en', 'fr', 'ko', 'ru'],
1616
menuItems : [{
1717
name : 'credits',
1818
handler : credits

0 commit comments

Comments
 (0)