diff options
author | Ryan Johnson <rjohnson@mozilla.com> | 2021-04-29 16:16:42 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-29 16:16:42 -0700 |
commit | 95aca4b4d8fa62815d4bd412fff1a364f842814a (patch) | |
tree | 5e57661720fe9058d5c7db637e764800b50f9060 /files/uk/web/javascript/eventloop | |
parent | ee3b1c87e3c8e72ca130943eed260ad642246581 (diff) | |
download | translated-content-95aca4b4d8fa62815d4bd412fff1a364f842814a.tar.gz translated-content-95aca4b4d8fa62815d4bd412fff1a364f842814a.tar.bz2 translated-content-95aca4b4d8fa62815d4bd412fff1a364f842814a.zip |
remove retired locales (#699)
Diffstat (limited to 'files/uk/web/javascript/eventloop')
-rw-r--r-- | files/uk/web/javascript/eventloop/index.html | 152 |
1 files changed, 0 insertions, 152 deletions
diff --git a/files/uk/web/javascript/eventloop/index.html b/files/uk/web/javascript/eventloop/index.html deleted file mode 100644 index ab47fd4b48..0000000000 --- a/files/uk/web/javascript/eventloop/index.html +++ /dev/null @@ -1,152 +0,0 @@ ---- -title: Модель конкурентності та цикл подій -slug: Web/JavaScript/EventLoop -tags: - - JavaScript - - обробники подій - - події - - цикл подій - - черга -translation_of: Web/JavaScript/EventLoop ---- -<div>{{JsSidebar("Advanced")}}</div> - -<p>JavaScript має модель одночасності, що базується на <strong>циклі подій</strong>, який є відповідальним за виконання коду, збір та обробку подій та виконання підзадач з черги. Ця модель доволі сильно відрізняється від моделей у інших мовах, таких як С та Java.</p> - -<h2 id="Концепції_виконання">Концепції виконання</h2> - -<p>Наступні розділи пояснють теоретичну модель. Сучасні імплементації JavaScript реалізують і значно оптимізують описану семантику.</p> - -<h3 id="Візуальне_відображення">Візуальне відображення</h3> - -<p style="text-align: center;"><img alt="Стек, купа, черга" src="https://mdn.mozillademos.org/files/17036/visual.png" style="height: 270px; width: 294px;"></p> - -<h3 id="Стек">Стек</h3> - -<p>Виклики функцій утворюють стек <em>фреймів (frames)</em>.</p> - -<pre class="brush: js">function foo(b) { - var a = 10; - return a + b + 11; -} - -function bar(x) { - var y = 3; - return foo(x * y); -} - -console.log(bar(7)); // вертає 42 -</pre> - -<p>Коли викликається <code><font face="Consolas, Liberation Mono, Courier, monospace">bar</font></code>, утворюється перший фрейм, який містить аргументи та локальні змінні функції <code>bar</code>. Коли <code><font face="Consolas, Liberation Mono, Courier, monospace">bar</font></code> викликає <code>foo</code>, створюється другий фрейм та розміщується над першим, він містить аргументи та локальні змінні функції <code>foo</code>. Коли <code>foo</code> повертає значення, верхній фрейм виштовхується зі стеку (залишаючи лише фрейм виклику <font face="Consolas, Liberation Mono, Courier, monospace"><code>bar</code></font>). Коли <code><font face="Consolas, Liberation Mono, Courier, monospace">bar</font></code> повертає значення, стек стає порожнім.</p> - -<h3 id="Купа">Купа</h3> - -<p>Об'єкти розподіляються у купі, яка є лише назвою для позначення великої (здебільшого не структурованої) області пам'яті.</p> - -<h3 id="Черга">Черга</h3> - -<p>Процес виконання JavaScript використовує чергу повідомлень, яка є списком повідомлень, що мають бути опрацьовані. Кожне повідомлення має пов'язану функцію, яка викликається для обробки цього повідомлення </p> - -<p>В певний момент {{anch("Цикл_подій", "циклу подій")}} процес виконання починає обробку повідомлень з черги, починаючи з найстаршого. Для цього повідомлення видаляється з черги, а його пов'язана функція викликається з повідомленням в якості вхідного параметра. Як завжди, виклик функції створює новий фрейм стеку для цієї функції.</p> - -<p>Опрацювання функцій продовжується, доки стек знову не стане порожнім. Тоді цикл подій опрацює наступне повідомлення у черзі (якщо воно є).</p> - -<h2 id="Цикл_подій">Цикл подій</h2> - -<p><strong>Цикл подій</strong> отримав свою назву через те, як він зазвичай реалізується. Як правило, це схоже на:</p> - -<pre class="brush: js">while (queue.waitForMessage()) { - queue.processNextMessage(); -}</pre> - -<p><code>queue.waitForMessage</code> синхронно чекає на прибуття повідомлення (якщо воно вже не надійшло і не чекає на обробку).</p> - -<h3 id="Виконання_до_завершення">"Виконання до завершення"</h3> - -<p>Кожне повідомлення обробляється до завершення, перш, ніж обробляти будь-яке інше повідомлення.</p> - -<p>Це надає деякі приємні властивості для вашої програми, в тому числі той факт, що, коли виконується функція, вона не може бути попередньо вилучена і виконається до кінця перш, ніж буде запущено будь-який інший код (і зможе змінювати дані, якими користується функція). Це відрізняється, наприклад, від C, де, якщо функція виконується у потоці, її можна зупинити в будь-якій точці, щоб запустити інший код в іншому потоці.</p> - -<p>Зворотним боком цієї моделі є те, що, якщо обробка повідомлення займає надто багато часу, веб-застосунок не може обробити взаємодії користувача, як-от натискання чи прокручування. Веб-переглядач пом'якшує це діалоговим вікном "a script is taking too long to run" (виконання сценарію займає забагато часу). Гарною практикою є робити обробку повідомлень короткою і, за можливості, розбивати одне повідомлення на декілька.</p> - -<h3 id="Додавання_повідомлень">Додавання повідомлень</h3> - -<p>У веб-переглядачах повідомлення додаються щоразу, коли виникає подія, до якої приєднаний прослуховувач подій. Якщо прослуховувача немає, подія втрачається. Отже, натискання на елементі з обробником подій натискання додасть повідомлення, так само з будь-якою іншою подією.</p> - -<p>Функція <code><a href="/uk/docs/Web/API/WindowTimers/setTimeout">setTimeout</a></code> викликається з двома аргументами: повідомлення, що додається до черги, та значення часу (необов'язкове; за замовчуванням <code>0</code>). <em>Значення часу </em>відображає (мінімальну) затримку, після якої повідомлення буде, власне, додане до черги. Якщо в черзі немає інших повідомлень, це повідомлення буде оброблене одразу після затримки. Однак, якщо там є повідомлення, повідомленню <code>setTimeout</code> доведеться зачекати, доки не будуть оброблені інші повідомлення. З цієї причини другий аргумент вказує <em>мінімальний</em>, а не гарантований час.</p> - -<p>Ось приклад, який демонструє цю концепцію (<code>setTimeout</code> не виконується негайно після того, як його таймер завершився): </p> - -<pre class="brush: js">const s = new Date().getSeconds(); - -setTimeout(function() { - // виводить "2", тобто, функція зворотного виклику не запустилась одразу через 500 мілісекунд. - console.log("Функція запустилась через " + (new Date().getSeconds() - s) + " секунд"); -}, 500) - -while (true) { - if (new Date().getSeconds() - s >= 2) { - console.log("Добре, виконувалось 2 секунди") - break; - } -}</pre> - -<h3 id="Нульові_затримки">Нульові затримки</h3> - -<p>Нульова затримка насправді не означає, що зворотній виклик запуститься через нуль мілісекунд. Виклик {{domxref ("WindowTimers.setTimeout", "setTimeout")}} із затримкою в <code>0</code> (нуль) мілісекунд не виконує функцію зворотного виклику після заданого інтервалу.</p> - -<p>Виконання залежить від кількості задач, що чекають у черзі. У наведеному нижче прикладі повідомлення <code>"це просто повідомлення"</code> буде написане у консоль раніше, ніж буде оброблене повідомлення у зворотному виклику, оскільки затримка - це <em>мінімальний</em> час, необхідний для обробки запиту (а не <em>гарантований</em> час).</p> - -<p>Загалом, <code>setTimeout</code> має чекати, доки виконається весь код для повідомлень у черзі, незважаючи на те, що ви вказали певний часовий ліміт для своєї функції <code>setTimeout</code>.</p> - -<pre class="brush: js">(function() { - - console.log('це початок'); - - setTimeout(function cb() { - console.log('Зворотний виклик 1: це повідомлення зворотного виклику'); - }); - - console.log('це просто повідомлення'); - - setTimeout(function cb1() { - console.log('Зворотний виклик 2: це повідомлення зворотного виклику'); - }, 0); - - console.log('це кінець'); - -})(); - -// "це початок" -// "це просто повідомлення" -// "це кінець" -// "Зворотний виклик 1: це повідомлення зворотного виклику" -// "Зворотний виклик 2: це повідомлення зворотного виклику" -</pre> - -<h3 id="Декілька_процесів_виконання_що_спілкуються_між_собою">Декілька процесів виконання, що спілкуються між собою</h3> - -<p>Веб-виконавець або iframe перехресного походження має свій стек, купу та чергу повідомлень. Два різних процеси виконання можуть спілкуватися надсиланням повідомлень за допомогою методу <a href="/uk/docs/Web/API/Window/postMessage"><code>postMessage</code></a>. Цей метод додає повідомлення до іншого процесу виконання, якщо останній прослуховує події <code>message</code>.</p> - -<h2 id="Жодного_блокування">Жодного блокування</h2> - -<p>Дуже цікавою властивістю моделі циклу подій є те, що JavaScript, на відміну від багатьох інших мов, ніколи не блокує. Управління введенням/виводом зазвичай здійснюється за допомогою подій та зворотних викликів, тому, коли програма чекає на результат запиту <a href="/uk/docs/Web/API/IndexedDB_API">IndexedDB</a> чи запиту <a href="/uk/docs/Web/API/XMLHttpRequest">XHR</a>, вона може опрацьовувати інші події, такі як введення даних користувачем.</p> - -<p>Існують спадкові винятки, такі як <code>alert</code> або синхронний XHR, але вважається гарною практикою їх уникати. Будьте обережні: <a href="http://stackoverflow.com/questions/2734025/is-javascript-guaranteed-to-be-single-threaded/2734311#2734311">існують винятки з винятку</a> (але зазвичай це помилки реалізації, а не що-небудь інше).</p> - -<h2 id="Специфікації">Специфікації</h2> - -<table class="standard-table"> - <tbody> - <tr> - <th scope="col">Специфікація</th> - </tr> - <tr> - <td>{{SpecName('HTML WHATWG', 'webappapis.html#event-loops', 'Event loops')}}</td> - </tr> - <tr> - <td><a href="https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/#what-is-the-event-loop">Node.js Event Loop</a></td> - </tr> - </tbody> -</table> |