Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit c6a27b4

Browse files
committedMar 4, 2025·
1.12.2
1 parent a9bebc2 commit c6a27b4

File tree

2 files changed

+191
-191
lines changed

2 files changed

+191
-191
lines changed
 
Lines changed: 180 additions & 180 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,51 @@
11

2-
# Async iteration and generators
2+
# Asynchronní iterace a generátory
33

4-
Asynchronous iteration allow us to iterate over data that comes asynchronously, on-demand. Like, for instance, when we download something chunk-by-chunk over a network. And asynchronous generators make it even more convenient.
4+
Asynchronní iterace nám umožňuje iterovat nad daty, která přicházejí asynchronně, na požádání. Například když něco stahujeme po částech ze sítě. A asynchronní generátory nám to ještě usnadňují.
55

6-
Let's see a simple example first, to grasp the syntax, and then review a real-life use case.
6+
Nejprve se podíváme na jednoduchý příklad, abychom pochopili syntaxi, a pak si prohlédneme případ použití z reálného života.
77

8-
## Recall iterables
8+
## Připomínka iterovatelných objektů
99

10-
Let's recall the topic about iterables.
10+
Připomeňme si téma iterovatelných objektů.
1111

12-
The idea is that we have an object, such as `range` here:
12+
Myšlenkou je, že máme objekt, například `rozsah` zde:
1313
```js
14-
let range = {
15-
from: 1,
16-
to: 5
14+
let rozsah = {
15+
začátek: 1,
16+
konec: 5
1717
};
1818
```
1919

20-
...And we'd like to use `for..of` loop on it, such as `for(value of range)`, to get values from `1` to `5`.
20+
...A rádi bychom nad ním používali cyklus `for..of`, např. `for(hodnota of rozsah)`, kterým budeme získávat hodnoty od `1` do `5`.
2121

22-
In other words, we want to add an *iteration ability* to the object.
22+
Jinými slovy, chceme přidat objektu *schopnost iterace*.
2323

24-
That can be implemented using a special method with the name `Symbol.iterator`:
24+
To můžeme implementovat pomocí speciální metody s názvem `Symbol.iterator`:
2525

26-
- This method is called in by the `for..of` construct when the loop is started, and it should return an object with the `next` method.
27-
- For each iteration, the `next()` method is invoked for the next value.
28-
- The `next()` should return a value in the form `{done: true/false, value:<loop value>}`, where `done:true` means the end of the loop.
26+
- Tato metoda je volána konstruktem `for..of`, když je cyklus zahájen, a měla by vrátit objekt obsahující metodu `next`.
27+
- Při každé iteraci je metoda `next()` volána pro další hodnotu.
28+
- Metoda `next()` by měla vrátit hodnotu ve tvaru `{done: true/false, value:<hodnota cyklu>}`, kde `done:true` znamená konec cyklu.
2929

30-
Here's an implementation for the iterable `range`:
30+
Zde je implementace iterovatelného objektu `rozsah`:
3131

3232
```js run
33-
let range = {
34-
from: 1,
35-
to: 5,
33+
let rozsah = {
34+
začátek: 1,
35+
konec: 5,
3636

3737
*!*
38-
[Symbol.iterator]() { // called once, in the beginning of for..of
38+
[Symbol.iterator]() { // voláno jednou, na začátku for..of
3939
*/!*
4040
return {
41-
current: this.from,
42-
last: this.to,
41+
aktuální: this.začátek,
42+
poslední: this.konec,
4343

4444
*!*
45-
next() { // called every iteration, to get the next value
45+
next() { // voláno při každé iteraci pro získání další hodnoty
4646
*/!*
47-
if (this.current <= this.last) {
48-
return { done: false, value: this.current++ };
47+
if (this.aktuální <= this.poslední) {
48+
return { done: false, value: this.aktuální++ };
4949
} else {
5050
return { done: true };
5151
}
@@ -54,54 +54,54 @@ let range = {
5454
}
5555
};
5656

57-
for(let value of range) {
58-
alert(value); // 1 then 2, then 3, then 4, then 5
57+
for(let hodnota of rozsah) {
58+
alert(hodnota); // 1, pak 2, pak 3, pak 4, pak 5
5959
}
6060
```
6161

62-
If anything is unclear, please visit the chapter [](info:iterable), it gives all the details about regular iterables.
62+
Pokud vám něco není jasné, prosíme navštivte kapitolu [](info:iterable), která vysvětluje všechny podrobnosti o běžných iterovatelných objektech.
6363

64-
## Async iterables
64+
## Asynchronní iterovatelné objekty
6565

66-
Asynchronous iteration is needed when values come asynchronously: after `setTimeout` or another kind of delay.
66+
Asynchronní iteraci potřebujeme, když hodnoty přicházejí asynchronně: po `setTimeout` nebo prodlevě jiného druhu.
6767

68-
The most common case is that the object needs to make a network request to deliver the next value, we'll see a real-life example of it a bit later.
68+
Nejběžnějším případem je, že objekt potřebuje k doručení další hodnoty vytvořit síťový požadavek. Příklad z reálného života uvidíme o něco později.
6969

70-
To make an object iterable asynchronously:
70+
Abychom učinili objekt asynchronně iterovatelným:
7171

72-
1. Use `Symbol.asyncIterator` instead of `Symbol.iterator`.
73-
2. The `next()` method should return a promise (to be fulfilled with the next value).
74-
- The `async` keyword handles it, we can simply make `async next()`.
75-
3. To iterate over such an object, we should use a `for await (let item of iterable)` loop.
76-
- Note the `await` word.
72+
1. Použijeme `Symbol.asyncIterator` místo `Symbol.iterator`.
73+
2. Metoda `next()` by měla vrátit příslib (aby byl splněn další hodnotou).
74+
- Zajistí to klíčové slovo `async`. Můžeme jednoduše vytvořit `async next()`.
75+
3. K iteraci nad takovým objektem bychom měli používat cyklus `for await (let prvek of iterovatelnýObjekt)`.
76+
- Všimněte si slova `await`.
7777

78-
As a starting example, let's make an iterable `range` object, similar like the one before, but now it will return values asynchronously, one per second.
78+
Jako počáteční příklad vytvořme iterovatelný objekt `rozsah`. Bude podobný tomu předchozímu, ale nyní bude vracet hodnoty asynchronně, jednu za sekundu.
7979

80-
All we need to do is to perform a few replacements in the code above:
80+
Vše, co musíme udělat, je provést několik náhrad ve výše uvedeném kódu:
8181

8282
```js run
83-
let range = {
84-
from: 1,
85-
to: 5,
83+
let rozsah = {
84+
začátek: 1,
85+
konec: 5,
8686

8787
*!*
8888
[Symbol.asyncIterator]() { // (1)
8989
*/!*
9090
return {
91-
current: this.from,
92-
last: this.to,
91+
aktuální: this.začátek,
92+
poslední: this.konec,
9393

9494
*!*
9595
async next() { // (2)
9696
*/!*
9797

9898
*!*
99-
// note: we can use "await" inside the async next:
100-
await new Promise(resolve => setTimeout(resolve, 1000)); // (3)
99+
// poznámka: uvnitř asynchronní funkce next můžeme použít „await“:
100+
await new Promise(splň => setTimeout(splň, 1000)); // (3)
101101
*/!*
102102

103-
if (this.current <= this.last) {
104-
return { done: false, value: this.current++ };
103+
if (this.aktuální <= this.poslední) {
104+
return { done: false, value: this.aktuální++ };
105105
} else {
106106
return { done: true };
107107
}
@@ -113,121 +113,121 @@ let range = {
113113
(async () => {
114114

115115
*!*
116-
for await (let value of range) { // (4)
117-
alert(value); // 1,2,3,4,5
116+
for await (let hodnota of rozsah) { // (4)
117+
alert(hodnota); // 1,2,3,4,5
118118
}
119119
*/!*
120120

121121
})()
122122
```
123123

124-
As we can see, the structure is similar to regular iterators:
124+
Jak vidíme, tato struktura se podobá obyčejným iterátorům:
125125

126-
1. To make an object asynchronously iterable, it must have a method `Symbol.asyncIterator` `(1)`.
127-
2. This method must return the object with `next()` method returning a promise `(2)`.
128-
3. The `next()` method doesn't have to be `async`, it may be a regular method returning a promise, but `async` allows us to use `await`, so that's convenient. Here we just delay for a second `(3)`.
129-
4. To iterate, we use `for await(let value of range)` `(4)`, namely add "await" after "for". It calls `range[Symbol.asyncIterator]()` once, and then its `next()` for values.
126+
1. Abychom učinili objekt asynchronně iterovatelným, musí obsahovat metodu `Symbol.asyncIterator` `(1)`.
127+
2. Tato metoda musí vracet objekt s metodou `next()`, která vrací příslib `(2)`.
128+
3. Metoda `next()` nemusí být `async`, může to být běžná metoda vracející příslib, ale `async` nám umožňuje použít `await`, takže je vhodné. Zde prostě sekundu počkáme `(3)`.
129+
4. K iteraci použijeme `for await(let hodnota of rozsah)` `(4)`, jmenovitě přidáme „await“ za „for“. Tento cyklus jedenkrát volá `rozsah[Symbol.asyncIterator]()` a pak pro získávání hodnot volá jeho `next()`.
130130

131-
Here's a small table with the differences:
131+
Uvedeme malou tabulku s rozdíly:
132132

133-
| | Iterators | Async iterators |
133+
| | Iterátory | Asynchronní iterátory |
134134
|-------|-----------|-----------------|
135-
| Object method to provide iterator | `Symbol.iterator` | `Symbol.asyncIterator` |
136-
| `next()` return value is | any value | `Promise` |
137-
| to loop, use | `for..of` | `for await..of` |
135+
Objektová metoda, která poskytne iterátor | `Symbol.iterator` | `Symbol.asyncIterator` |
136+
| Návratová hodnota `next()` je | libovolná hodnota | `Promise` |
137+
| K iteraci se používá | `for..of` | `for await..of` |
138138

139-
````warn header="The spread syntax `...` doesn't work asynchronously"
140-
Features that require regular, synchronous iterators, don't work with asynchronous ones.
139+
````warn header="Roztažená syntaxe `...` asynchronně nefunguje"
140+
Prvky jazyka, které vyžadují obvyklé, synchronní iterátory, nefungují s asynchronními.
141141

142-
For instance, a spread syntax won't work:
142+
Nebude fungovat například roztažená syntaxe:
143143
```js
144-
alert( [...range] ); // Error, no Symbol.iterator
144+
alert( [...rozsah] ); // Chyba, není Symbol.iterator
145145
```
146146

147-
That's natural, as it expects to find `Symbol.iterator`, not `Symbol.asyncIterator`.
147+
To je přirozené, protože ta očekává `Symbol.iterator`, ne `Symbol.asyncIterator`.
148148

149-
It's also the case for `for..of`: the syntax without `await` needs `Symbol.iterator`.
149+
To je také případ cyklu `for..of`: syntaxe bez `await` potřebuje `Symbol.iterator`.
150150
````
151151
152-
## Recall generators
152+
## Připomínka generátorů
153153
154-
Now let's recall generators, as they allow to make iteration code much shorter. Most of the time, when we'd like to make an iterable, we'll use generators.
154+
Nyní si připomeňme generátory, protože ty nám umožňují iterační kód značně zkrátit. Když bychom rádi vytvořili iterovatelný objekt, většinou použijeme generátory.
155155
156-
For sheer simplicity, omitting some important stuff, they are "functions that generate (yield) values". They are explained in detail in the chapter [](info:generators).
156+
Pro zjednodušení, když vypustíme některé důležité věci, to jsou „funkce, které generují (vydávají) hodnoty“. Jsou podrobně vysvětleny v kapitole [](info:generators).
157157
158-
Generators are labelled with `function*` (note the star) and use `yield` to generate a value, then we can use `for..of` to loop over them.
158+
Generátory jsou označeny jako `function*` (všimněte si hvězdičky) a ke generování hodnot používají `yield`. Pak nad nimi můžeme procházet cyklem `for..of`.
159159
160-
This example generates a sequence of values from `start` to `end`:
160+
Tento příklad generuje posloupnost hodnot od `začátek` po `konec`:
161161
162162
```js run
163-
function* generateSequence(start, end) {
164-
for (let i = start; i <= end; i++) {
163+
function* generujPosloupnost(začátek, konec) {
164+
for (let i = začátek; i <= konec; i++) {
165165
yield i;
166166
}
167167
}
168168
169-
for(let value of generateSequence(1, 5)) {
170-
alert(value); // 1, then 2, then 3, then 4, then 5
169+
for(let hodnota of generujPosloupnost(1, 5)) {
170+
alert(hodnota); // 1, pak 2, pak 3, pak 4, pak 5
171171
}
172172
```
173173
174-
As we already know, to make an object iterable, we should add `Symbol.iterator` to it.
174+
Jak už víme, abychom učinili objekt iterovatelným, měli bychom do něj přidat `Symbol.iterator`.
175175
176176
```js
177-
let range = {
178-
from: 1,
179-
to: 5,
177+
let rozsah = {
178+
začátek: 1,
179+
konec: 5,
180180
*!*
181181
[Symbol.iterator]() {
182-
return <object with next to make range iterable>
182+
return <objekt s metodou next, aby rozsah byl iterovatelný>
183183
}
184184
*/!*
185185
}
186186
```
187187
188-
A common practice for `Symbol.iterator` is to return a generator, it makes the code shorter, as you can see:
188+
Běžnou praxí pro `Symbol.iterator` je vrátit generátor, tím se kód zkrátí, jak vidíte:
189189
190190
```js run
191-
let range = {
192-
from: 1,
193-
to: 5,
191+
let rozsah = {
192+
začátek: 1,
193+
konec: 5,
194194
195-
*[Symbol.iterator]() { // a shorthand for [Symbol.iterator]: function*()
196-
for(let value = this.from; value <= this.to; value++) {
197-
yield value;
195+
*[Symbol.iterator]() { // zkratka pro [Symbol.iterator]: function*()
196+
for(let hodnota = this.začátek; hodnota <= this.konec; hodnota++) {
197+
yield hodnota;
198198
}
199199
}
200200
};
201201
202-
for(let value of range) {
203-
alert(value); // 1, then 2, then 3, then 4, then 5
202+
for(let hodnota of rozsah) {
203+
alert(hodnota); // 1, pak 2, pak 3, pak 4, pak 5
204204
}
205205
```
206206
207-
Please see the chapter [](info:generators) if you'd like more details.
207+
Pokud by vás zajímaly další podrobnosti, přečtěte si prosíme kapitolu [](info:generators).
208208
209-
In regular generators we can't use `await`. All values must come synchronously, as required by the `for..of` construct.
209+
V obyčejných generátorech nemůžeme používat `await`. Všechny hodnoty musejí přicházet synchronně, jak vyžaduje konstrukt `for..of`.
210210
211-
What if we'd like to generate values asynchronously? From network requests, for instance.
211+
Co kdybychom chtěli generovat hodnoty asynchronně, například ze síťových požadavků?
212212
213-
Let's switch to asynchronous generators to make it possible.
213+
Přejděme k asynchronním generátorům, které nám to umožní.
214214
215-
## Async generators (finally)
215+
## Asynchronní generátory (konečně)
216216
217-
For most practical applications, when we'd like to make an object that asynchronously generates a sequence of values, we can use an asynchronous generator.
217+
Když chceme vytvořit objekt, který asynchronně generuje posloupnost hodnot, ve většině praktických aplikací můžeme použít asynchronní generátor.
218218
219-
The syntax is simple: prepend `function*` with `async`. That makes the generator asynchronous.
219+
Syntaxe je jednoduchá: před `function*` uvedeme `async`. To učiní generátor asynchronním.
220220
221-
And then use `for await (...)` to iterate over it, like this:
221+
A pak k iteraci nad ním použijeme `for await (...)`, například:
222222
223223
```js run
224-
*!*async*/!* function* generateSequence(start, end) {
224+
*!*async*/!* function* generujPosloupnost(začátek, konec) {
225225
226-
for (let i = start; i <= end; i++) {
226+
for (let i = začátek; i <= konec; i++) {
227227
228228
*!*
229-
// Wow, can use await!
230-
await new Promise(resolve => setTimeout(resolve, 1000));
229+
// Hurá, můžeme použít await!
230+
await new Promise(splň => setTimeout(splň, 1000));
231231
*/!*
232232
233233
yield i;
@@ -237,181 +237,181 @@ And then use `for await (...)` to iterate over it, like this:
237237
238238
(async () => {
239239
240-
let generator = generateSequence(1, 5);
241-
for *!*await*/!* (let value of generator) {
242-
alert(value); // 1, then 2, then 3, then 4, then 5 (with delay between)
240+
let generátor = generujPosloupnost(1, 5);
241+
for *!*await*/!* (let hodnota of generátor) {
242+
alert(hodnota); // 1, pak 2, pak 3, pak 4, pak 5 (s prodlevou mezi nimi)
243243
}
244244
245245
})();
246246
```
247247
248-
As the generator is asynchronous, we can use `await` inside it, rely on promises, perform network requests and so on.
248+
Jelikož je generátor asynchronní, můžeme uvnitř něj používat `await`, spoléhat se na přísliby, provádět síťové požadavky a podobně.
249249
250-
````smart header="Under-the-hood difference"
251-
Technically, if you're an advanced reader who remembers the details about generators, there's an internal difference.
250+
````smart header="Rozdíl pod kapotou"
251+
Jestliže jste pokročilý čtenář a pamatujete si podrobnosti o generátorech, je tady technicky vnitřní rozdíl.
252252
253-
For async generators, the `generator.next()` method is asynchronous, it returns promises.
253+
U asynchronních generátorů je metoda `generátor.next()` asynchronní, vrací přísliby.
254254
255-
In a regular generator we'd use `result = generator.next()` to get values. In an async generator, we should add `await`, like this:
255+
V obyčejném generátoru bychom k získávání hodnot použili `výsledek = generator.next()`. V asynchronním generátoru bychom měli přidat `await`, například takto:
256256
257257
```js
258-
result = await generator.next(); // result = {value: ..., done: true/false}
258+
výsledek = await generator.next(); // výsledek = {value: ..., done: true/false}
259259
```
260-
That's why async generators work with `for await...of`.
260+
Z tohoto důvodu asynchronní generátory fungují s `for await...of`.
261261
````
262262

263-
### Async iterable range
263+
### Asynchronní iterovatelný rozsah
264264

265-
Regular generators can be used as `Symbol.iterator` to make the iteration code shorter.
265+
Jako `Symbol.iterator` můžeme používat obyčejné generátory, aby byl iterační kód kratší.
266266

267-
Similar to that, async generators can be used as `Symbol.asyncIterator` to implement the asynchronous iteration.
267+
Obdobně můžeme jako `Symbol.asyncIterator` používat asynchronní generátory, abychom implementovali asynchronní iteraci.
268268

269-
For instance, we can make the `range` object generate values asynchronously, once per second, by replacing synchronous `Symbol.iterator` with asynchronous `Symbol.asyncIterator`:
269+
Například můžeme přimět objekt `rozsah`, aby generoval hodnoty asynchronně, jednu za sekundu, nahrazením synchronního `Symbol.iterator` za asynchronní `Symbol.asyncIterator`:
270270

271271
```js run
272-
let range = {
273-
from: 1,
274-
to: 5,
272+
let rozsah = {
273+
začátek: 1,
274+
konec: 5,
275275

276-
// this line is same as [Symbol.asyncIterator]: async function*() {
276+
// tento řádek je totéž jako [Symbol.asyncIterator]: async function*() {
277277
*!*
278278
async *[Symbol.asyncIterator]() {
279279
*/!*
280-
for(let value = this.from; value <= this.to; value++) {
280+
for(let hodnota = this.začátek; hodnota <= this.konec; hodnota++) {
281281

282-
// make a pause between values, wait for something
283-
await new Promise(resolve => setTimeout(resolve, 1000));
282+
// učiňme přestávku mezi hodnotami, na něco čekáme
283+
await new Promise(splň => setTimeout(splň, 1000));
284284

285-
yield value;
285+
yield hodnota;
286286
}
287287
}
288288
};
289289

290290
(async () => {
291291

292-
for *!*await*/!* (let value of range) {
293-
alert(value); // 1, then 2, then 3, then 4, then 5
292+
for *!*await*/!* (let hodnota of rozsah) {
293+
alert(hodnota); // 1, pak 2, pak 3, pak 4, pak 5
294294
}
295295

296296
})();
297297
```
298298

299-
Now values come with a delay of 1 second between them.
299+
Nyní hodnoty přicházejí s prodlevou 1 sekunda mezi sebou.
300300

301301
```smart
302-
Technically, we can add both `Symbol.iterator` and `Symbol.asyncIterator` to the object, so it's both synchronously (`for..of`) and asynchronously (`for await..of`) iterable.
302+
Technicky můžeme do objektu přidat `Symbol.iterator` i `Symbol.asyncIterator` současně, bude tedy iterovatelný jak synchronně (`for..of`), tak asynchronně (`for await..of`).
303303
304-
In practice though, that would be a weird thing to do.
304+
V praxi by to však bylo podivné.
305305
```
306306

307-
## Real-life example: paginated data
307+
## Příklad z reálného života: stránkovaná data
308308

309-
So far we've seen basic examples, to gain understanding. Now let's review a real-life use case.
309+
Dosud jsme viděli základní příklady, abychom tomu porozuměli. Nyní se podívejme na případ použití z reálného života.
310310

311-
There are many online services that deliver paginated data. For instance, when we need a list of users, a request returns a pre-defined count (e.g. 100 users) - "one page", and provides a URL to the next page.
311+
Existuje mnoho online služeb, které doručují stránkovaná data. Například když potřebujeme seznam uživatelů, požadavek vrátí předdefinovaný počet (např. 100 uživatelů) -- „jednu stránku“ a poskytne URL další stránky.
312312

313-
This pattern is very common. It's not about users, but just about anything.
313+
Tento vzorec je zcela běžný. Neplatí to jen pro uživatele, ale v zásadě pro cokoli.
314314

315-
For instance, GitHub allows us to retrieve commits in the same, paginated fashion:
315+
Například GitHub nám umožňuje získávat commity stejným způsobem, po stránkách:
316316

317-
- We should make a request to `fetch` in the form `https://api.github.com/repos/<repo>/commits`.
318-
- It responds with a JSON of 30 commits, and also provides a link to the next page in the `Link` header.
319-
- Then we can use that link for the next request, to get more commits, and so on.
317+
- Měli bychom vytvořit požadavek do `fetch` ve tvaru `https://api.github.com/repos/<úložiště>/commits`.
318+
- GitHub odpoví JSONem se 30 commity a také nám v hlavičce `Link` poskytne odkaz na další stránku.
319+
- Tento odkaz pak můžeme použít pro další požadavek, k získání dalších commitů, a tak dále.
320320

321-
For our code, we'd like to have a simpler way to get commits.
321+
V našem kódu bychom rádi měli jednodušší způsob, jak získávat commity.
322322

323-
Let's make a function `fetchCommits(repo)` that gets commits for us, making requests whenever needed. And let it care about all pagination stuff. For us it'll be a simple async iteration `for await..of`.
323+
Vytvořme funkci `stáhniCommity(úložiště)`, která nám bude načítat commity a bude vytvářet požadavky, kdykoli budou zapotřebí. A nechme ji, aby se postarala o všechny záležitosti ohledně stránkování. Pro nás to bude jednoduchá asynchronní iterace `for await..of`.
324324

325-
So the usage will be like this:
325+
Použití tedy bude následující:
326326

327327
```js
328-
for await (let commit of fetchCommits("username/repository")) {
329-
// process commit
328+
for await (let commit of stáhniCommity("uživatel/úložiště")) {
329+
// zpracování commitu
330330
}
331331
```
332332

333-
Here's such function, implemented as async generator:
333+
Zde je taková funkce, implementovaná jako asynchronní generátor:
334334

335335
```js
336-
async function* fetchCommits(repo) {
337-
let url = `https://api.github.com/repos/${repo}/commits`;
336+
async function* stáhniCommityložiště) {
337+
let url = `https://api.github.com/repos/${úložiště}/commits`;
338338

339339
while (url) {
340-
const response = await fetch(url, { // (1)
341-
headers: {'User-Agent': 'Our script'}, // github needs any user-agent header
340+
const odpověď = await fetch(url, { // (1)
341+
headers: {'User-Agent': 'Our script'}, // GitHub potřebuje hlavičku s uživatelským agentem
342342
});
343343

344-
const body = await response.json(); // (2) response is JSON (array of commits)
344+
const tělo = await odpověď.json(); // (2) odpověď v JSONu (pole commitů)
345345

346-
// (3) the URL of the next page is in the headers, extract it
347-
let nextPage = response.headers.get('Link').match(/<(.*?)>; rel="next"/);
348-
nextPage = nextPage?.[1];
346+
// (3) v hlavičkách je URL další stránky, vydolujeme ho
347+
let dalšíStránka = odpověď.headers.get('Link').match(/<(.*?)>; rel="next"/);
348+
dalšíStránka = dalšíStránka?.[1];
349349

350-
url = nextPage;
350+
url = dalšíStránka;
351351

352-
for(let commit of body) { // (4) yield commits one by one, until the page ends
352+
for(let commit of tělo) { // (4) vydáme commity jeden po druhém, dokud stránka neskončí
353353
yield commit;
354354
}
355355
}
356356
}
357357
```
358358
359-
More explanations about how it works:
359+
Podrobnější vysvětlení, jak to funguje:
360360
361-
1. We use the browser [fetch](info:fetch) method to download the commits.
361+
1. K načtení commitů používáme metodu prohlížeče [fetch](info:fetch).
362362
363-
- The initial URL is `https://api.github.com/repos/<repo>/commits`, and the next page will be in the `Link` header of the response.
364-
- The `fetch` method allows us to supply authorization and other headers if needed -- here GitHub requires `User-Agent`.
365-
2. The commits are returned in JSON format.
366-
3. We should get the next page URL from the `Link` header of the response. It has a special format, so we use a regular expression for that (we will learn this feature in [Regular expressions](info:regular-expressions)).
367-
- The next page URL may look like `https://api.github.com/repositories/93253246/commits?page=2`. It's generated by GitHub itself.
368-
4. Then we yield the received commits one by one, and when they finish, the next `while(url)` iteration will trigger, making one more request.
363+
- Úvodní URL je `https://api.github.com/repos/<úložiště>/commits` a další stránka bude v hlavičce odpovědi `Link`.
364+
- Metoda `fetch` nám umožňuje poskytnout autorizaci a další hlavičky, pokud jsou zapotřebí -- zde GitHub vyžaduje hlavičku `User-Agent`.
365+
2. Commity jsou vráceny ve formátu JSON.
366+
3. Z hlavičky `Link` odpovědi bychom měli získat URL další stránky. Hlavička má speciální formát, takže pro ni použijeme regulární výraz (o tomto prvku jazyka se dozvíme v kapitole [Regulární výrazy](info:regular-expressions)).
367+
- URL další stránky může vypadat jako `https://api.github.com/repositories/93253246/commits?page=2`. Generuje je samotný GitHub.
368+
4. Pak budeme vydávat získané commity jeden po druhém, a když dojdou, spustí se další iterace `while(url)`, která vytvoří další požadavek.
369369

370-
An example of use (shows commit authors in console):
370+
Příklad použití (zobrazí na konzoli autory commitů):
371371

372372
```js run
373373
(async () => {
374374
375-
let count = 0;
375+
let počet = 0;
376376
377-
for await (const commit of fetchCommits('javascript-tutorial/en.javascript.info')) {
377+
for await (const commit of stáhniCommity('javascript-tutorial/en.javascript.info')) {
378378
379379
console.log(commit.author.login);
380380
381-
if (++count == 100) { // let's stop at 100 commits
381+
if (++počet == 100) { // zastavíme se po 100 commitech
382382
break;
383383
}
384384
}
385385
386386
})();
387387
388-
// Note: If you are running this in an external sandbox, you'll need to paste here the function fetchCommits described above
388+
// Poznámka: Pokud tohle spouštíte v externím pískovišti, musíte sem zkopírovat výše uvedenou funkci stáhniCommity
389389
```
390390

391-
That's just what we wanted.
391+
To je přesně to, co jsme chtěli.
392392

393-
The internal mechanics of paginated requests is invisible from the outside. For us it's just an async generator that returns commits.
393+
Vnitřní mechaniky stránkovaných požadavků jsou zvnějšku neviditelné. Pro nás je to prostě jen asynchronní generátor, který vrací commity.
394394

395-
## Summary
395+
## Shrnutí
396396

397-
Regular iterators and generators work fine with the data that doesn't take time to generate.
397+
Obyčejné iterátory a generátory fungují dobře s daty, jejichž generování netrvá dlouhou dobu.
398398

399-
When we expect the data to come asynchronously, with delays, their async counterparts can be used, and `for await..of` instead of `for..of`.
399+
Když očekáváme, že data budou přicházet asynchronně s prodlevami, můžeme použít jejich asynchronní protějšky a `for await..of` místo `for..of`.
400400

401-
Syntax differences between async and regular iterators:
401+
Syntaktické rozdíly mezi asynchronními a běžnými iterátory:
402402

403-
| | Iterable | Async Iterable |
403+
| | Iterovatelný objekt | Asynchronní iterovatelný objekt |
404404
|-------|-----------|-----------------|
405-
| Method to provide iterator | `Symbol.iterator` | `Symbol.asyncIterator` |
406-
| `next()` return value is | `{value:…, done: true/false}` | `Promise` that resolves to `{value:…, done: true/false}` |
405+
| Metoda poskytující iterátor | `Symbol.iterator` | `Symbol.asyncIterator` |
406+
| Návratová hodnota `next()` je | `{value:…, done: true/false}` | `Promise`, který se splní s `{value:…, done: true/false}` |
407407

408-
Syntax differences between async and regular generators:
408+
Syntaktické rozdíly mezi asynchronními a běžnými generátory:
409409

410-
| | Generators | Async generators |
410+
| | Generátory | Asynchronní generátory |
411411
|-------|-----------|-----------------|
412-
| Declaration | `function*` | `async function*` |
413-
| `next()` return value is | `{value:…, done: true/false}` | `Promise` that resolves to `{value:…, done: true/false}` |
412+
| Deklarace | `function*` | `async function*` |
413+
| Návratová hodnota `next()` je | `{value:…, done: true/false}` | `Promise`, který se splní s `{value:…, done: true/false}` |
414414

415-
In web-development we often meet streams of data, when it flows chunk-by-chunk. For instance, downloading or uploading a big file.
415+
Při vývoji webů se často setkáváme s proudy dat, která přitékají po částech, například při stahování nebo odesílání velkého souboru.
416416

417-
We can use async generators to process such data. It's also noteworthy that in some environments, like in browsers, there's also another API called Streams, that provides special interfaces to work with such streams, to transform the data and to pass it from one stream to another (e.g. download from one place and immediately send elsewhere).
417+
Ke zpracování takových dat můžeme používat asynchronní generátory. Stojí také za zmínku, že v některých prostředích, např. v prohlížečích, existuje i další API nazvané Streams, které poskytuje speciální rozhraní pro práci s takovými proudy (streamy), pro transformaci dat a jejich předávání z jednoho proudu do druhého (např. při stahování z jednoho místa a okamžitém odesílání jinam).

‎1-js/12-generators-iterators/2-async-iterators-generators/head.html

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
<script>
2-
async function* fetchCommits(repo) {
3-
let url = `https://api.github.com/repos/${repo}/commits`;
2+
async function* stáhniCommity(úložiště) {
3+
let url = `https://api.github.com/repos/${úložiště}/commits`;
44

55
while (url) {
6-
const response = await fetch(url, {
7-
headers: {'User-Agent': 'Our script'}, // github requires user-agent header
6+
const odpověď = await fetch(url, {
7+
headers: {'User-Agent': 'Our script'}, // GitHub potřebuje hlavičku s uživatelským agentem
88
});
99

10-
const body = await response.json(); // parses response as JSON (array of commits)
10+
const tělo = await odpověď.json(); // parsuje odpověď v JSONu (pole commitů)
1111

12-
// the URL of the next page is in the headers, extract it
13-
let nextPage = response.headers.get('Link').match(/<(.*?)>; rel="next"/);
14-
nextPage = nextPage?.[1];
12+
// v hlavičkách je URL další stránky, vydolujeme ho
13+
let dalšíStránka = odpověď.headers.get('Link').match(/<(.*?)>; rel="next"/);
14+
dalšíStránka = dalšíStránka?.[1];
1515

16-
url = nextPage;
16+
url = dalšíStránka;
1717

18-
// yield commits one by one, when they finish - fetch a new page url
19-
for(let commit of body) {
18+
// vydáme commity jeden po druhém, dokud stránka neskončí - pak stáhneme stránku z dalšího URL
19+
for(let commit of tělo) {
2020
yield commit;
2121
}
2222
}

0 commit comments

Comments
 (0)
Please sign in to comment.