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/1-generators/article.md
+3-98Lines changed: 3 additions & 98 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,128 +11,91 @@
11
11
ظاهر یک تابع generator به صورت زیر است:
12
12
13
13
```js
14
-
15
14
function*generateSequence() {
16
-
17
15
yield1;
18
-
19
16
yield2;
20
-
21
17
return3;
22
-
23
18
}
24
-
25
19
```
26
20
27
-
28
21
توابع generator با توابع معمول، رفتار متفاوتی دارند. زمانی که این توابع صدا میشوند، بدنه آنها اجرا نمیشود؛ در عوض، یک آبجکت خاص به نام "generator object" برمیگردانند که به وسیله آن اجرای تابع را میتوان کنترل کرد.
29
22
30
23
برای مثال:
31
24
32
25
```js run
33
-
34
26
function*generateSequence() {
35
-
36
27
yield1;
37
-
38
28
yield2;
39
-
40
29
return3;
41
-
42
30
}
43
31
44
32
//برمیگرداند generator یک آبجکت generator تابع
45
-
46
33
let generator =generateSequence();
47
-
48
34
\*!*
49
-
50
35
alert(generator); // [object Generator]
51
-
52
36
\*/!*
53
-
54
37
```
55
38
56
-
57
39
اجرای بدنه تابع هنوز شروع نشده است:
58
40
59
41

60
42
61
43
متد اصلی یک آبجکت generator متد `()next` است. هنگامی که صدا میشود، بدنه تابع تا اولین `yield value` اجرا میشود(`value` میتواند حذف شود که در این صورت `undefined` است.)؛ سپس اجرای تابع متوقف میشود و مقدار yield شده برگرداننده میشود.
62
44
63
45
مقدار برگردانده شده توسط متود `next` همواره یک آبجکت با 2 پراپرتی است:
64
-
65
46
-`value`: مقدار برگرداننده شده توسط `yield`.
66
-
67
47
-`done`: یک Boolean است که در صورت اتمام بدنه تابع مقدار true و در غیر این صورت مقدار false دارد.
68
48
69
49
برای مثال، در کد زیر، یک آبجکت generator ایجاد شده و اولین مقدار `yield` شده توسط آن گرفته شده است:
با استفاد از `for..of` میتوان از `value` آنها استفاده کرد:
143
106
144
107
```js run
145
-
146
108
function* generateSequence() {
147
-
148
109
yield 1;
149
-
150
110
yield 2;
151
-
152
111
return 3;
153
-
154
112
}
155
113
156
114
let generator = generateSequence();
157
115
158
116
for(let value of generator) {
159
-
160
117
alert(value); // ابتدا 1 و سپس 2
161
-
162
118
}
163
-
164
119
````
165
120
166
121
این شیوه از صدا کردن `next` تمیزتر است؛ اینگونه فکر نمیکنید؟
167
122
168
123
...اما دقت کنید: مثال بالا ابتدا `1` و سپس `2` را نشان داد؛ خبری از `3` نیست!
169
124
170
125
علت این اتفاق این است که `for..of` آخرین مقدار را هنگامی که `done:true` است در نظر نمیگیرد. هنگام برگرداندن آخرین مقدار با `return`، بر خلاف `done:true`، `yield` است. در نتیجه برای نشان دادن تمام مقادیر باید آنها را با `yield` برگردانیم:
171
-
```js run
172
126
127
+
```js run
173
128
function*generateSequence() {
174
-
175
129
yield1;
176
-
177
130
yield2;
178
-
179
131
\*!*
180
-
181
132
yield3;
182
-
183
133
\*/!*
184
-
185
134
}
186
135
187
136
let generator =generateSequence();
188
137
189
138
for(let value of generator) {
190
-
191
139
alert(value); // ابتدا 1 سپس 2 و بعد از آن 3
192
-
193
140
}
194
-
195
141
```
196
142
197
-
198
143
از آنجایی که generatorها iterable هستند، از تمام functionality آنها نیز برای generatorها میتوان استفاده کرد؛ مثل spread syntax `...`:
199
144
200
145
```js run
201
-
202
146
function*generateSequence() {
203
-
204
147
yield1;
205
-
206
148
yield2;
207
-
208
149
yield3;
209
-
210
150
}
211
151
212
152
let sequence = [0, ...generateSequence()];
213
153
214
154
alert(sequence); // 0, 1, 2, 3
215
-
216
155
```
217
156
218
-
219
157
در کد بالا، `()generateSequence...`، باعث میشود آبجکت generator که iterable هم هست به آرایهای از اعداد تبدیل شود.(درباره spread syntax در چپتر [](info:rest-parameters-spread#spread-syntax) بیشتر بخوانید.)
0 commit comments