1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
---
title: for await...of
slug: Web/JavaScript/Reference/Statements/for-await...of
tags:
- JavaScript
- async
- Асинхронность
translation_of: Web/JavaScript/Reference/Statements/for-await...of
---
<div>{{jsSidebar("Statements")}}</div>
<p>Выражение <strong><code>for await...of</code> </strong>создаёт цикл, проходящий через асинхронные итерируемые объекты, а также синхронные итерируемые сущности, включающие: встроенные {{jsxref("String")}}, {{jsxref("Array")}}, <code>Array</code>-подобные объекты (например., {{jsxref("Functions/arguments", "arguments")}} или {{domxref("NodeList")}}), {{jsxref("TypedArray")}}, {{jsxref("Map")}}, {{jsxref("Set")}}, а также определяемые пользователем асинхронные/синхронные сущности. Он вызывает пользовательский итерационный хук с инструкциями, которые должны быть выполнены для значения каждого отдельного свойства объекта.</p>
<p class="hidden">Исходный код этого интерактивного примера хранится в репозитории GitHub. Если вы хотите внести свой вклад в проект интерактивных примеров, пожалуйста, склонируйте <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> и отправьте нам пулреквест.</p>
<h2 id="Синтаксис">Синтаксис</h2>
<pre class="syntaxbox">for await (<em>variable</em> of <em>iterable</em>) {
<em>statement
</em>}
</pre>
<dl>
<dt><code>variable</code></dt>
<dd>На каждой итерации значение другого свойства присваивается <em>variable</em>. <em>variable</em> может быть объявлена с помощью ключевых слов <code>const</code>, <code>let</code>, or <code>var</code>.</dd>
<dt><code>iterable</code></dt>
<dd>Объект, чьи итерируемые свойства будут повторяться.</dd>
</dl>
<h3 id="Итерирование_по_асинхронным_переменным">Итерирование по асинхронным переменным</h3>
<p>Вы также можете перебрать объект, который явно реализует асинхронный итерируемый протокол.</p>
<pre class="brush:js">var asyncIterable = {
[Symbol.asyncIterator]() {
return {
i: 0,
next() {
if (this.i < 3) {
return Promise.resolve({ value: this.i++, done: false });
}
return Promise.resolve({ done: true });
}
};
}
};
(async function() {
for await (let num of asyncIterable) {
console.log(num);
}
})();
// 0
// 1
// 2
</pre>
<h3 id="Итерирование_по_асинхронным_генераторам.">Итерирование по асинхронным генераторам</h3>
<p>Поскольку асинхронные генераторы реализуют асинхронный протокол Iterator, по ним можно пройти циклом с помощью <code>for await... of</code></p>
<pre class="brush: js">async function* asyncGenerator() {
var i = 0;
while (i < 3) {
yield i++;
}
}
(async function() {
for await (let num of asyncGenerator()) {
console.log(num);
}
})();
// 0
// 1
// 2</pre>
<p>Для более конкретного примера перебора асинхронного генератора с помощью <code>for await... of</code>, рассмотрим перебор данных из API. В этом примере сначала создаётся асинхронный итератор для потока данных, а затем он используется для определения размера ответа от API.</p>
<pre class="brush: js">async function* streamAsyncIterator(stream) {
const reader = stream.getReader();
try {
while (true) {
const { done, value } = await reader.read();
if (done) {
return;
}
yield value;
}
} finally {
reader.releaseLock();
}
}
// Fetches data from url and calculates response size using the async generator.
async function getResponseSize(url) {
const response = await fetch(url);
// Will hold the size of the response, in bytes.
let responseSize = 0;
// The for-await-of loop. Async iterates over each portion of the response.
for await (const chunk of streamAsyncIterator(response.body)) {
// Incrementing the total response length.
responseSize += chunk.length;
}
console.log(`Response Size: ${responseSize} bytes`);
// expected output: "Response Size: 1071472"
return responseSize;
}
getResponseSize('https://jsonplaceholder.typicode.com/photos');</pre>
<h2 id="Спецификации">Спецификации</h2>
{{Specifications}}
<h2 id="Браузерная_совместимость">Браузерная совместимость</h2>
<div>{{Compat}}</div>
<h2 id="Смотрите_также">Смотрите также</h2>
<ul>
<li>{{jsxref("Statements/for...of")}}</li>
</ul>
|