You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 1-js/12-generators-iterators/2-async-iterators-generators/article.md
+24-24Lines changed: 24 additions & 24 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,11 +1,11 @@
1
1
2
2
# Iteração assíncrona e geradores
3
3
4
-
A iteração assíncrona permite que iteremos sobre dados que são gerados de forma assíncrona, sob demanda. Por exemplo, ao baixarmos algo pedaço por pedaço pela rede. E os geradores assíncronos tornam isso ainda mais conveniente.
4
+
A iteração assíncrona nos permite iterar sobre dados que são gerados de forma assíncrona, sob demanda. Por exemplo, ao baixarmos algo pedaço por pedaço pela rede. E os geradores assíncronos tornam isso ainda mais conveniente.
5
5
6
6
Vamos ver primeiro um exemplo simples para compreender a sintaxe e, em seguida, revisaremos um caso de uso da vida real.
7
7
8
-
## Relembrando iteráveis
8
+
## Relembrar os iteráveis
9
9
10
10
Vamos relembrar o tópico sobre iteráveis.
11
11
@@ -18,7 +18,7 @@ let range = {
18
18
};
19
19
```
20
20
21
-
... E gostaríamos de usar o loop for..of nele, como for(valor of range), para obter valores de 1 a 5.
21
+
... E gostaríamos de usar o loop `for..of` nele, como for(valor of range), para obter valores de 1 a 5.
22
22
23
23
Em outras palavras, queremos adicionar uma capacidade de iteração ao objeto.
24
24
@@ -59,7 +59,7 @@ for(let value of range) {
59
59
alert(value); // 1, depois 2, depois 3, depois 4, depois 5
60
60
}
61
61
```
62
-
Se algo não estiver claro, consulte o capítulo [](info:iterable), que fornece todos os detalhes sobre iteráveis regulares.
62
+
Se algo não estiver claro, consulte o capítulo [](info:iterable), que fornece todos os detalhes sobre iteráveis tradicionais.
63
63
64
64
## Iteráveis assíncronos
65
65
@@ -72,7 +72,7 @@ Para tornar um objeto iterável de forma assíncrona:
72
72
1. Use `Symbol.asyncIterator` em vez de `Symbol.iterator`.
73
73
2. O método `next()` deve retornar uma promise (para ser resolvida com o próximo valor).
74
74
- A palavra-chave `async` cuida disso, podemos simplesmente fazer `async next()`.
75
-
3. Para iterar sobre esse objeto, devemos usar um lopp`for await (let item of iterable)`.
75
+
3. Para iterar sobre esse objeto, devemos usar um loop`for await (let item of iterable)`.
76
76
- Observe a palavra-chave `await`.
77
77
78
78
Como exemplo inicial, vamos fazer um objeto iterável `range`, semelhante ao anterior, mas agora ele retornará valores de forma assíncrona, um por segundo.
@@ -96,7 +96,7 @@ let range = {
96
96
*/!*
97
97
98
98
*!*
99
-
// observe: podemos usar "await" dentro de async next:
99
+
// observe: podemos usar o "await" dentro de async next:
Como podemos ver, a estrutura é semelhante aos iteradores regulares:
123
+
Como podemos ver, a estrutura é semelhante aos iteradores tradicionais:
124
124
125
125
1. Para criar um objeto iterável de forma assíncrona, ele deve ter um método `Symbol.asyncIterator``(1)`.
126
126
2. Este método deve retornar o objeto com o método `next()` que retorna uma promise `(2)`
@@ -135,7 +135,7 @@ Aqui está uma pequena tabela com as diferenças:
135
135
| Para fazer um loop, use |`for..of`|`for await..of`|
136
136
137
137
````warn header="A sintaxe spread `...` não funciona de forma assíncrona"
138
-
Recursos que exigem iteradores regulares, síncronos, não funcionam com iteradores assíncronos.
138
+
Recursos que exigem iteradores tradicionais, síncronos, não funcionam com iteradores assíncronos.
139
139
140
140
Por exemplo, a sintaxe de spread não funcionará:
141
141
```js
@@ -153,7 +153,7 @@ Agora, vamos relembrar os geradores, pois eles permitem encurtar o código de it
153
153
154
154
Por pura simplicidade, omitindo algumas coisas importantes, eles são "funções que geram (yield) valores". Eles são explicados em detalhes no capítulo [](info:generators).
155
155
156
-
Os geradores são rotulados com `function*` (observe o asterisco) e usam `yield` para gerar um valor, então podemos usar `for..of` para fazer loop sobre eles.
156
+
Os geradores são rotulados com `function*` (observe o asterisco) e usam `yield` para gerar um valor, então podemos usar `for..of` para iterar sobre eles.
157
157
158
158
Este exemplo gera uma sequência de valores de `start` a `end`:
159
159
@@ -204,7 +204,7 @@ for(let value of range) {
204
204
205
205
Consulte o capítulo [](info:generators) se desejar mais detalhes.
206
206
207
-
Em geradores regulares, não podemos usar `await`. Todos os valores devem vir de forma síncrona, conforme exigido pelo construtor `for..of`.
207
+
Em geradores tradicionais, não podemos usar o `await`. Todos os valores devem vir de forma síncrona, conforme exigido pelo construtor `for..of`.
208
208
209
209
E se quisermos gerar valores de forma assíncrona? De solicitações de rede, por exemplo.
210
210
@@ -248,9 +248,9 @@ Como o gerador é assíncrono, podemos usar `await` dentro dele, fazê-lo depend
248
248
````smart header="Diferença de baixo dos panos"
249
249
Tecnicamente, se você é um leitor avançado que se lembra dos detalhes dos geradores, há uma diferença interna.
250
250
251
-
Para geradores assíncrono, o método `generator.next()` é assíncrono, ele retorna promises.
251
+
Para geradores assíncronos, o método `generator.next()` é assíncrono, ele retorna promises.
252
252
253
-
Em um gerador regular usaríamos `result = generator.next()` para obter valores. Em um gerador assíncrono, devemos adicionar `await`, assim:
253
+
Em um gerador tradicional usaríamos `result = generator.next()` para obter valores. Em um gerador assíncrono, devemos adicionar `await`, assim:
254
254
255
255
```js
256
256
result = await generator.next(); // result = {value: ..., done: true/false}
@@ -260,7 +260,7 @@ result = await generator.next(); // result = {value: ..., done: true/false}
260
260
261
261
### Async iterable range
262
262
263
-
Geradores regulares podem ser usados como `Symbol.iterator` para tornar o código de iteração mais curto.
263
+
Geradores tradicionais podem ser usados como `Symbol.iterator` para tornar o código de iteração mais curto.
264
264
265
265
Semelhante a isso, geradores assíncronos podem ser usados como `Symbol.asyncIterator` para implementar a iteração assíncrona.
266
266
@@ -310,9 +310,9 @@ Existem muitos serviços online que entregam dados paginados. Por exemplo, ao so
310
310
311
311
Esse padrão é bem comum. Não só com usuários, mas com qualquer coisa.
312
312
313
-
Por exemplo, GitHub nos permite recuperar commits da mesma maneira paginados:
313
+
Por exemplo, GitHub nos permite recuperar commits da mesma maneira, de forma paginada:
314
314
315
-
- Devemos fazer uma requisição ao `fetch` no formato `https://api.github.com/repos/<repo>/commits`.
315
+
- Devemos fazer uma requisição `fetch` no formato `https://api.github.com/repos/<repo>/commits`.
316
316
- Ela responde com um JSON contendo 30 commits e também fornece um link para a próxima pagina no cabeçalho `Link`.
317
317
- Podemos usar este link para a próxima requisição para obter mais commits, e assim por diante.
1. Usamos o o método do navegador [fetch](info:fetch) para baixar os commits.
358
+
1. Usamos o método [fetch](info:fetch) do navegador para baixar os commits.
359
359
360
-
- A URL inicial é `https://api.github.com/repos/<repo>/commits` e a próxima página estará no cabeçalho `Link` da resposta.
361
-
-O método `fetch` nos permite fornecer cabeçalhos de autorização e outros caso necessário -- aqui o GitHub requer o `User-Agent`.
360
+
- A URL inicial é `https://api.github.com/repos/<repo>/commits` e a próxima página estará no cabeçalho `Link` da resposta.
361
+
-O método `fetch` nos permite fornecer cabeçalhos de autorização e outros caso necessário -- aqui o GitHub requer o `User-Agent`.
362
362
2. Os commits são retornados no formato JSON.
363
363
3. Devemos obter a URL da próxima página do cabeçalho `Link` da resposta. Ele tem um formato especial, então usamos uma expressão regular para isso (vamos aprender essa funcionalidade em [Expressões regulares](info:regular-expressions))
364
364
-AURL da próxima página deve parecer com `https://api.github.com/repositories/93253246/commits?page=2`. É gerada pelo próprio GitHub.
@@ -384,30 +384,30 @@ Um exemplo de uso (mostra os autores dos commits no console):
384
384
// Observe: Se você está rodando isso em um ambiente externo, você precisará colar aqui a função fetchCommits descrita acima.
385
385
```
386
386
387
-
Isso é apenas o que queremos.
387
+
Isso é exatamente o que queremos.
388
388
389
389
A mecânica interna das requisições paginadas é invisível para quem está do lado de fora. Para nós, é apenas um gerador assíncrono que retorna commits.
390
390
391
391
## Resumo
392
392
393
-
Iteradores regulares e geradores funcionam bem com dados que não levam tempo para serem gerados.
393
+
Iteradores tradicionais e geradores funcionam bem com dados que não levam tempo para serem gerados.
394
394
395
395
Quando esperamos que os dados cheguem de forma assíncrona, com atrasos, podemos usar suas contrapartes assíncronas e `for await..of` em vez de `for..of`.
396
396
397
-
Diferenças de sintaxe entre iteradores assíncronos e regulares:
397
+
Diferenças de sintaxe entre iteradores assíncronos e tradicionais:
398
398
399
399
|| Iterável | Iterável assíncrono |
400
400
|-------|-----------|-----------------|
401
401
|Método para fornecer um iterador |`Symbol.iterator`|`Symbol.asyncIterator`|
402
402
| valor retornado por `next()` é |`{value:…, done: true/false}`|`Promise` que se resolve para `{value:…, done: true/false}`|
403
403
404
-
Diferenças de sintaxe entre geradores assíncronos e regulares:
404
+
Diferenças de sintaxe entre geradores assíncronos e tradicionais:
405
405
406
406
|| Geradores | Geradores assíncronos |
407
407
|-------|-----------|-----------------|
408
408
| Declaração |`function*`|`async function*`|
409
-
| valor retornado por `next()` é |`{value:…, done: true/false}`|`Promise` que se resolve para `{value:…, done: true/false}`|
409
+
| valor retornado por `next()` é |`{value:…, done: true/false}`|`Promise` que se resolve para `{value:…, done: true/false}`|
410
410
411
-
Na área de desenvolvimento web, frequentemente nos deparamos com fluxos de dados, nos quais os dados fluem parte por parte. Por exemplo, ao baixar ou enviar um arquivo grande.
411
+
Na área de desenvolvimento web, frequentemente nos deparamos com fluxos de dados, nos quais os dados fluem pedaço por pedaço. Por exemplo, ao baixar ou enviar um arquivo grande.
412
412
413
413
Podemos usar geradores assíncronos para processar esses tipos de dados. Também é importante mencionar que em alguns ambientes, como em navegadores, existe outra API chamada Streams, que fornece interfaces especiais para trabalhar com esses fluxos, transformar dados e transmiti-los de um fluxo para outro (por exemplo, baixar de um local e enviar imediatamente para outro).
0 commit comments