diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:43:23 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:43:23 -0500 |
commit | 218934fa2ed1c702a6d3923d2aa2cc6b43c48684 (patch) | |
tree | a9ef8ac1e1b8fe4207b6d64d3841bfb8990b6fd0 /files/uk/web/javascript/reference/statements/for-await...of/index.html | |
parent | 074785cea106179cb3305637055ab0a009ca74f2 (diff) | |
download | translated-content-218934fa2ed1c702a6d3923d2aa2cc6b43c48684.tar.gz translated-content-218934fa2ed1c702a6d3923d2aa2cc6b43c48684.tar.bz2 translated-content-218934fa2ed1c702a6d3923d2aa2cc6b43c48684.zip |
initial commit
Diffstat (limited to 'files/uk/web/javascript/reference/statements/for-await...of/index.html')
-rw-r--r-- | files/uk/web/javascript/reference/statements/for-await...of/index.html | 253 |
1 files changed, 253 insertions, 0 deletions
diff --git a/files/uk/web/javascript/reference/statements/for-await...of/index.html b/files/uk/web/javascript/reference/statements/for-await...of/index.html new file mode 100644 index 0000000000..9c0440c346 --- /dev/null +++ b/files/uk/web/javascript/reference/statements/for-await...of/index.html @@ -0,0 +1,253 @@ +--- +title: for await...of +slug: Web/JavaScript/Reference/Statements/for-await...of +tags: + - JavaScript + - await + - Інструкція + - асинхронний + - перебір +translation_of: Web/JavaScript/Reference/Statements/for-await...of +--- +<div>{{jsSidebar("Statements")}}</div> + +<p><strong>Інструкція</strong> <strong><code>for await...of</code> </strong>створює цикл, що перебирає як асинхронні ітерабельні об'єкти, так і синхронні ітерабельні об'єкти, в тому числі вбудовані {{jsxref("String")}}, {{jsxref("Array")}}, подібні до масивів об'єкти (наприклад, {{jsxref("Functions/arguments", "arguments")}} чи {{DOMxRef("NodeList")}}), {{jsxref("TypedArray")}}, {{jsxref("Map")}}, {{jsxref("Set")}}, а також визначені користувачем асинхронні/синхронні ітерабельні об'єкти. Вона викликає користувацький хук до ітерацій з командами, що виконуватимуться для значення кожної окремої властивості об'єкта. Як і оператор {{jsxref("Operators/await", "await")}}, інструкція може використовуватись лише всередині {{jsxref("Statements/async_function", "асинхронної функції")}}.</p> + +<div class="blockIndicator note"> +<p><code>for await...of</code> не працює з асинхронними ітераторами, які не є асинхронними ітерабельними об'єктами.</p> +</div> + + + +<h2 id="Синтаксис">Синтаксис</h2> + +<pre class="syntaxbox">for await (<var>variable</var> of <var>iterable</var>) { + <var>statement</var> +} +</pre> + +<dl> + <dt><code><var>variable</var></code></dt> + <dd>На кожній ітерації значення іншої властивості присвоюється змінній <code><var>variable</var></code>. Змінна <code><var>variable</var></code> може бути оголошена через <code>const</code>, <code>let</code> або <code>var</code>.</dd> + <dt><code><var>iterable</var></code></dt> + <dd>Об'єкт, чиї ітерабельні властивості перебираються.</dd> +</dl> + +<h2 id="Приклади">Приклади</h2> + +<h3 id="Перебір_асинхронних_ітерабельних_обєктів">Перебір асинхронних ітерабельних об'єктів</h3> + +<p>Ви також можете перебирати об'єкт, який явно реалізує протокол асинхронного ітерабельного об'єкта:</p> + +<pre class="brush:js">const 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>Оскільки значення, що повертають асинхронні генератори, відповідають протоколу асинхронного ітерабельного об'єкта, їх можна перебирати циклом <code>for await...of</code>.</p> + +<pre class="brush: js">async function* asyncGenerator() { + let 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.</p> + +<p>Цей приклад спочатку створює асинхронний ітерабельний об'єкт для потоку даних, а далі використовує його, щоб дізнатись розмір відповіді від API.</p> + +<pre class="brush: js">async function* streamAsyncIterable(stream) { + const reader = stream.getReader(); + try { + while (true) { + const { done, value } = await reader.read(); + if (done) { + return; + } + yield value; + } + } finally { + reader.releaseLock(); + } +} +// Отримує дані з URL та обчислює розмір відповіді за допомогою +// асинхронного генератора. +async function getResponseSize(url) { + const response = await fetch(url); + // Міститиме розмір відповіді, у байтах. + let responseSize = 0; + // Цикл for-await-of. Асинхронно перебирає кожну частку відповіді. + for await (const chunk of streamAsyncIterable(response.body)) { + // Збільшує загальну довжину відповіді. + responseSize += chunk.length; + } + + console.log(`Розмір відповіді: ${responseSize} байтів`); + // очікуваний результат: "Розмір відповіді: 1071472 байтів" + return responseSize; +} +getResponseSize('https://jsonplaceholder.typicode.com/photos');</pre> + +<h3 id="Перебір_синхронних_ітерабельних_обєктів_та_генераторів">Перебір синхронних ітерабельних об'єктів та генераторів</h3> + +<p>Цикл <code>for await...of</code> також споживає синхронні ітерабельні об'єкти та генератори. У цьому випадку він внутрішньо чекає на видані значення перед тим, як присвоювати їх керівній змінній циклу.</p> + +<pre class="brush: js">function* generator() { + yield 0; + yield 1; + yield Promise.resolve(2); + yield Promise.resolve(3); + yield 4; +} + +(async function() { + for await (let num of generator()) { + console.log(num); + } +})(); +// 0 +// 1 +// 2 +// 3 +// 4 + +// порівняйте з циклом for-of: + +for (let numOrPromise of generator()) { + console.log(numOrPromise); +} +// 0 +// 1 +// Promise { 2 } +// Promise { 3 } +// 4 +</pre> + +<div></div> + +<div class="blockIndicator note"> +<p><strong>Заувага</strong>: остерігайтеся видавати відхилені проміси з синхронного генератора. У цьому випадку <code>for await...of</code> викидає виняток при споживанні відхиленого проміса та НЕ ВИКЛИКАЄ блоки <code>finally</code> всередині цього генератора. Це може бути небажаним, якщо вам треба звільнити певні виділені ресурси за допомогою <code>try/finally</code>.</p> +</div> + +<pre class="brush: js">function* generatorWithRejectedPromises() { + try { + yield 0; + yield 1; + yield Promise.resolve(2); + yield Promise.reject(3); + yield 4; + throw 5; + } finally { + console.log('викликано finally') + } +} + +(async function() { + try { + for await (let num of generatorWithRejectedPromises()) { + console.log(num); + } + } catch (e) { + console.log('перехоплено', e) + } +})(); +// 0 +// 1 +// 2 +// перехоплено 3 + +// порівняйте з циклом for-of: + +try { + for (let numOrPromise of generatorWithRejectedPromises()) { + console.log(numOrPromise); + } +} catch (e) { + console.log('перехоплено', e) +} +// 0 +// 1 +// Promise { 2 } +// Promise { <rejected> 3 } +// 4 +// перехоплено 5 +// викликано finally +</pre> + +<p>Для того, щоб блоки <code>finally</code> у синхронному генераторі завжди викликались, використовуйте належну форму циклу, <code>for await...of</code> для асинхронних генераторів та <code>for...of</code> для синхронних, та чекайте на видані проміси явно всередині циклу.</p> + +<pre class="brush: js">(async function() { + try { + for (let numOrPromise of generatorWithRejectedPromises()) { + console.log(await numOrPromise); + } + } catch (e) { + console.log('перехоплено', e) + } +})() +// 0 +// 1 +// 2 +// перехоплено 3 +// викликано finally</pre> + +<h2 id="Специфікації">Специфікації</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Специфікація</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ESDraft', '#sec-for-in-and-for-of-statements', 'ECMAScript Language: The for-in, for-of, and for-await-of Statements')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Сумісність_з_веб-переглядачами">Сумісність з веб-переглядачами</h2> + + + +<p>{{Compat("javascript.statements.for_await_of")}}</p> + +<h2 id="Див._також">Див. також</h2> + +<ul> + <li>{{jsxref("Global_Objects/Symbol/asyncIterator", "Symbol.asyncIterator")}}</li> + <li>{{jsxref("Statements/for...of", "for...of")}}</li> +</ul> |