11
2- # Async iteration and generators
2+ # แแกแแแฅแ แแแฃแแ แแขแแ แแชแแ แแ แแแแแ แแขแแ แแแ
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+ แแกแแแฅแ แแแฃแแ แแขแแ แแชแแ แกแแจแฃแแแแแแก แแแแซแแแแก แแแแแแฃแงแแแ แแกแแแฅแ แแแฃแแแ แแแฆแแแฃแ แแแแแชแแแก. แแแแแแแแแ, แ แแแแกแแช แฅแกแแแแแแ แแแฌแแ-แแแฌแแ แแแฌแแ แ แ แแแแแก. แแกแแแฅแ แแแฃแแ แแแแแ แแขแแ แแแ แแ แงแแแแแคแแ แก แแแแแแแแแขแแชแแแก แฃแคแ แ แแแแคแแ แขแฃแแก แฎแแแก .
55
6- Let's see a simple example first, to grasp the syntax, and then review a real-life use case .
6+ แแแแ แฏแแ แแแ แขแแแ แแแแแแแแ แแแแฎแแ, แแแแแแแ แกแแแขแแฅแกแ แ แแแแ แแ แแ แจแแแแแ แ แแแแฃแ แ แแแแแแแแ แแแแแแฎแแแแ .
77
8- ## Recall iterables
8+ ## แแแแแฎแกแแแแ แแขแแ แแขแแ แแแ
99
10- Let's recall the topic about iterables.
10+ แแแแ แแแแแฎแกแแแแ แแขแแ แแขแแ แแแแก แแแแ.
1111
12- The idea is that we have an object, such as ` range ` here :
12+ แแแฃ แแแแฅแแก แแแแแฅแขแ, แ แแแแ แแชแแ ` range ` :
1313``` js
1414let range = {
1515 from: 1 ,
1616 to: 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+ ...แแ แแแแแแ แแแแแแแงแแแแ ` for..of ` แชแแแแ, แ แแแแ แแชแแ ` for(value of range) ` , แ แแ แแแแแแ แแแ แแแแจแแแแแแแแแ ` 1 ` -แแแ ` 5 ` -แแแ .
2121
22- In other words, we want to add an * iteration ability * to the object .
22+ แกแฎแแ แกแแขแงแแแแแ, แฉแแแ แแแแแแ * แแขแแ แแชแแแก แฃแแแ แ * แแแแฃแแแขแแ แแแแแฅแขแก .
2323
24- That can be implemented using a special method with the name ` Symbol.iterator ` :
24+ แแแแก แแแกแแฆแฌแแแแ แกแแญแแ แแ แกแแแชแแแแฃแ แ แแแแแแแก แแแแแงแแแแแ ` 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+ - แแ แแแแแแก แแแแแแซแแฎแแแก ` for..of ` แชแแแแแก แแแกแแฌแงแแกแจแ แแแแแแซแแฎแแแก, แแ แแแ แฃแแแ แแแแแ แฃแแแก แแแแแฅแขแ ` next ` แแแแแแแ .
27+ - แงแแแแ แแขแแ แแชแแแแ, ` next() ` แแแแแแ แจแแแแแแ แแแแจแแแแแแแแก แแแกแแฆแแแแ แแแแแแซแแฎแแแ .
28+ - ` next() ` -แแแ แฃแแแ แแแแแ แฃแแแก แแแแจแแแแแแแ แคแแ แแแ ` {done: true/false, value:<แชแแแแแก แแแแจแแแแแแแ >} ` , แกแแแแช ` done:true ` แชแแแแแก แแแกแแกแ แฃแแก แแแจแแแแก .
2929
30- Here's an implementation for the iterable ` range ` :
30+ แฅแแแแแ แแแชแแแฃแแแ แแขแแ แแ แแแแแ ` range ` -แแก แแแแแแแแแขแแชแแ :
3131
3232``` js run
3333let range = {
3434 from: 1 ,
3535 to: 5 ,
3636
3737* ! *
38- [Symbol .iterator ]() { // called once, in the beginning of for..of
38+ [Symbol .iterator ]() { // แแแแแแซแแฎแแแ แแฎแแแแ แแ แแฎแแ, for..of-แแก แแแกแแฌแงแแกแจแ
3939*/ ! *
4040 return {
4141 current: this .from ,
4242 last: this .to ,
4343
4444* ! *
45- next () { // called every iteration, to get the next value
45+ next () { // แแแแแแซแแฎแแแ แงแแแแ แแขแแ แแชแแแแ แจแแแแแแ แแแแจแแแแแแแแก แแแกแแแ แแแแ
4646*/ ! *
4747 if (this .current <= this .last ) {
4848 return { done: false , value: this .current ++ };
@@ -59,25 +59,25 @@ for(let value of range) {
5959}
6060```
6161
62- If anything is unclear, please visit the chapter [ ] ( info:iterable ) , it gives all the details about regular iterables .
62+ แแฃ แ แแแ แแแฃแแแแแ แแ, แแฌแแแแ แแแแก [ แแขแแ แแขแแ แแแ ] ( info:iterable ) , แฉแแแฃแแแแ แแ แแขแแ แแขแแ แแแแ แแแคแแ แแแชแแแก แแแกแแฆแแแแ .
6363
64- ## Async iterables
64+ ## แแกแแแฅแ แแแฃแแ แแขแแ แแขแแ แแแ
6565
66- Asynchronous iteration is needed when values come asynchronously: after ` setTimeout ` or another kind of delay.
66+ แแกแแแฅแ แแแฃแแ แแขแแ แแชแแ แกแแญแแ แแ แ แแแแกแแช แแแแจแแแแแแแแแก แแกแแแฅแ แแแฃแแแ แแแฆแแแ: ` setTimeout ` -แแก แแ แแแแแแแแแ แ แจแแแคแแ แฎแแแแแก แจแแแแแ.
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+ แงแแแแแแ แฎแจแแ แ แจแแแแฎแแแแแ แ แแแแกแแช แแแแแฅแขแ แฅแกแแแก แ แแฅแฃแแกแแก แแแฃแแแแแแแก แ แแ แจแแแแแแ แแแแจแแแแแแแ แแแแฆแแก, แชแแขแ แฎแแแจแ แ แแแแฃแ แแแแแแแแกแแช แแแแแแฎแแแแแ .
6969
70- To make an object iterable asynchronously :
70+ แแแแกแแแแแก แ แแ แแแแแฅแขแ แแกแแแฅแ แแแฃแแแ แแขแแ แแ แแแแแ แแแฅแชแแแ, แฃแแแ :
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 . แแแแแแแงแแแแ ` Symbol.asyncIterator ` ` Symbol.iterator ` -แแก แแแแแแ แแ .
73+ 2 . ` next() ` แแแแแแแ แฃแแแ แแแแแ แฃแแแก "แแแแแ แแแ" ( promise, แแ แแแช "แคแ แแแแกแก" แแแแแแแงแแแแ), แ แแแ แจแแแแแแ แแแแจแแแแแแแแ แจแแแแกแแก .
74+ - ` async ` แฅแแแแ แแ แแแฎแแแแแก แแ แกแแขแฃแแชแแแก, แจแแแแแซแแแ แแแ แแแแแ ` async next() ` แแแแแแแงแแแแ .
75+ 3 . แแกแแ แแแแแฅแขแก แ แแ แแแแแแฃแงแแแ, แฃแแแ แแแแแแแงแแแแ ` for await (let item of iterable) ` แชแแแแ .
76+ - แงแฃแ แแแฆแแแ แแแแฅแชแแแ ` 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+ แแแแ แแแกแแฌแงแแกแแกแแแแก แจแแแฅแแแแ แฌแแแ ` range ` -แแก แแแแแแ แ แแแแแฅแขแ, แแแแ แแ แแแฏแแ แแช แแก แแแแแ แฃแแแแขแก แแกแแแฅแ แแแฃแ แแแแจแแแแแแแแแก แงแแแแ แแ แ แฌแแแจแ .
7979
80- All we need to do is to perform a few replacements in the code above:
80+ แแฎแแแ แ แแแแแแแแ แชแแแแแแแแก แจแแขแแแ แแแแแแฌแแแก.
8181
8282``` js run
8383let range = {
@@ -96,7 +96,7 @@ let range = {
9696*/ ! *
9797
9898* ! *
99- // note: we can use "await" inside the async next:
99+ // แแแแแแแ แแแ, แฉแแแ แจแแแแแซแแแ "await" แแแแแแแงแแแแ async next-แจแ :
100100 await new Promise (resolve => setTimeout (resolve, 1000 )); // (3)
101101*/ ! *
102102
@@ -121,32 +121,33 @@ let range = {
121121})()
122122```
123123
124- As we can see, the structure is similar to regular iterators :
124+ แ แแแแ แชแ แฎแแแแแ, แแแแแ แกแขแ แฃแฅแขแฃแ แ แแฅแแก แ แแแแ แช แฉแแแฃแแแแ แแ แแขแแ แแขแแ แก :
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 . แแแแกแแแแแก แ แแ แแแแแฅแขแ แแแแฎแแแแ แแกแแแฅแ แแแฃแแแ แแขแแ แแ แแแแแ, แแแก แฃแแแ แฐแฅแแแแแก แแแOแแ ` Symbol.asyncIterator ` ` (1) ` .
127+ 2 . แแ แแแแแแแ แฃแแแ แแแแแ แฃแแแก แแแแแฅแขแ ` async next()` แแแแแแแ ` (2) ` .
128+ 3 . ` next() ` แแแแแแ แแ แแ แกแแแแแแแแฃแแ แแงแแก ` async ` , แแก แจแแแซแแแแ แแงแแก แฉแแแฃแแแแ แแแ แแแแแแ แ แแแแแแช แแแ แฃแแแแก แคแ แแแแกแก, แแแแ แแ ` async ` แกแแจแฃแแแแแแก แแแแซแแแแก ` await ` -แแก แแแแแงแแแแแแก แแ แแแแขแแ แฃแคแ แ แแแแคแแ แขแฃแแแ. ` (3) ` แแฅ แฉแแแ แฃแแ แแแแ 1 แฌแแแ แแแคแแ แฎแแแ .
129+ 4 . แแขแแ แแชแแแก แฉแแแ แแแงแแแแแ ` for await (let value of range) ` ` (4) ` , แแ แแแแแแแฌแงแแแ "await"-แแก แแแแแขแแแ "for"-แแก แจแแแแแ. แแก แแซแแฎแแแก ` range[Symbol.asyncIterator]() ` -แก แแ แแฎแแ, แแ แจแแแแแ ` next() ` -แก แแแแแแแแ แแแแจแแแแแแแแแแกแแแแก .
130130
131- Here's a small table with the differences :
131+ แฅแแแแแ แชแฎแ แแแจแ แแแแแแแแฃแแแ แแแแกแฎแแแแแแแแ :
132132
133- | | Iterators | Async iterators |
133+ | | แแขแแ แแขแแ แแแ | แแกแแแฅแ แแแฃแแ แแขแแ แแขแแ แแแ |
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+ | แแแแแฅแขแแก แแแแแแ แแขแแ แแชแแแก แแแแแกแแชแแแแ | ` Symbol.iterator ` | ` Symbol.asyncIterator ` |
136+ | ` next() ` แ แแกแแช แแแ แฃแแแแก | any value | ` Promise ` |
137+ | แแขแแ แแชแแแกแแแแก แแแแแงแแแแแฃแแ แชแแแแ | ` for..of ` | ` for await..of ` |
138138
139- ````warn header="The spread syntax ` ... ` doesn't work asynchronously "
139+ ````warn header="แแแจแแแก แแแแ แแขแแ แก ` ... ` แแกแแแฅแ แแแฃแ แกแแขแฃแแชแแแจแ แแแ แแแแแแแงแแแแแ "
140140Features that require regular, synchronous iterators, don't work with asynchronous ones.
141+ แกแแแฅแ แแแฃแแ แแขแแ แแขแแ แแแแก แแแแกแแแแแก แแกแแแฅแ แแแฃแแแแแแ แแแ แแแแแแแงแแแแแ.
141142
142- For instance, a spread syntax won't work :
143+ แแแแแแแแแ, แแแจแแ แแแแ แแขแแ แ แแ แแแฃแจแแแแแก :
143144``` js
144145alert ( [... range] ); // Error, no Symbol.iterator
145146```
146147
147- That's natural, as it expects to find ` Symbol.iterator ` , not ` Symbol.asyncIterator ` .
148+ แแแฃ แแฃแแแแ แแแแ, แ แแแแแ แแก แชแแแแแแก แแแซแแแแแก ` Symbol.iterator ` แแ แแ แ ` Symbol.asyncIterator ` .
148149
149- It's also the case for ` for..of ` : the syntax without ` await ` needs ` Symbol.iterator ` .
150+ แแแแแ แกแแขแฃแแชแแแ ` for..of ` -แแแแก: ` await ` -แแก แแแ แแจแ แแฎแแแแ ` Symbol.iterator ` -แแแ แจแแแแแซแแแ แแแแแแแงแแแแ .
150151````
151152
152153## Recall generators
0 commit comments