diff options
Diffstat (limited to 'files/ru/learn/javascript/asynchronous')
4 files changed, 89 insertions, 89 deletions
diff --git a/files/ru/learn/javascript/asynchronous/async_await/index.html b/files/ru/learn/javascript/asynchronous/async_await/index.html index bef0f49847..4c0c08ae33 100644 --- a/files/ru/learn/javascript/asynchronous/async_await/index.html +++ b/files/ru/learn/javascript/asynchronous/async_await/index.html @@ -11,7 +11,7 @@ translation_of: Learn/JavaScript/Asynchronous/Async_await <div>{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Promises", "Learn/JavaScript/Asynchronous/Choosing_the_right_approach", "Learn/JavaScript/Asynchronous")}}</div> -<p class="summary">В ECMAScript версии 2017 появились <a href="/en-US/docs/Web/JavaScript/Reference/Statements/async_function">async functions</a> и ключевое слово <code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/await">await</a></code> (<a href="/en-US/docs/Web/JavaScript/New_in_JavaScript/ECMAScript_Next_support_in_Mozilla">ECMAScript Next support in Mozilla</a>). По существу, такие функции есть синтаксический сахар над Promises и Generator functions (<a href="https://tc39.es/ecmascript-asyncawait/">ts39</a>). С их помощью легче писать/читать асинхронный код, ведь они позволяют использовать привычный синхронный стиль написания. В этой статье мы на базовом уровне разберемся в их устройстве.</p> +<p class="summary">В ECMAScript версии 2017 появились <a href="/en-US/docs/Web/JavaScript/Reference/Statements/async_function">async functions</a> и ключевое слово <code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/await">await</a></code> (<a href="/en-US/docs/Web/JavaScript/New_in_JavaScript/ECMAScript_Next_support_in_Mozilla">ECMAScript Next support in Mozilla</a>). По существу, такие функции есть синтаксический сахар над Promises и Generator functions (<a href="https://tc39.es/ecmascript-asyncawait/">ts39</a>). С их помощью легче писать/читать асинхронный код, ведь они позволяют использовать привычный синхронный стиль написания. В этой статье мы на базовом уровне разберёмся в их устройстве.</p> <table class="learn-box standard-table"> <tbody> @@ -41,7 +41,7 @@ hello();</pre> <p>Функция возвращает "Hello" — ничего необычного, верно ?</p> -<p>Но что если мы сделаем ее асинхронной ? Проверим:</p> +<p>Но что если мы сделаем её асинхронной ? Проверим:</p> <pre class="brush: js notranslate">async function hello() { return "Hello" }; hello();</pre> @@ -63,16 +63,16 @@ hello();</pre> <pre class="brush: js notranslate">hello().then((value) => console.log(value))</pre> -<p>или еще короче</p> +<p>или ещё короче</p> <pre class="brush: js notranslate">hello().then(console.log) </pre> -<p>Итак, ключевое слово <code>async</code>, превращает обычную функцию в асинхронную и результат вызова функции оборачивает в Promise. Также асинхронная функция позволяет использовать в своем теле ключевое слово await, о котором далее.</p> +<p>Итак, ключевое слово <code>async</code>, превращает обычную функцию в асинхронную и результат вызова функции оборачивает в Promise. Также асинхронная функция позволяет использовать в своём теле ключевое слово await, о котором далее.</p> <h3 id="Ключевое_слово_await">Ключевое слово await</h3> -<p>Асинхронные функции становятся по настоящему мощными, когда вы используете ключевое слово <a href="/en-US/docs/Web/JavaScript/Reference/Operators/await">await</a> — по факту, <strong><code>await</code> работает только в асинхронных функциях</strong>. Мы можем использовать await перед promise-based функцией, чтобы остановить поток выполнения и дождаться результата ее выполнения (результат Promise). В то же время, остальной код нашего приложения не блокируется и продолжает работать.</p> +<p>Асинхронные функции становятся по настоящему мощными, когда вы используете ключевое слово <a href="/en-US/docs/Web/JavaScript/Reference/Operators/await">await</a> — по факту, <strong><code>await</code> работает только в асинхронных функциях</strong>. Мы можем использовать await перед promise-based функцией, чтобы остановить поток выполнения и дождаться результата её выполнения (результат Promise). В то же время, остальной код нашего приложения не блокируется и продолжает работать.</p> <p>Вы можете использовать <code>await</code> перед любой функцией, что возвращает Promise, включая Browser API функции.</p> @@ -84,7 +84,7 @@ hello();</pre> hello().then(alert);</pre> -<p>Конечно, на практике код выше бесполезен, но в учебных целях он иллюстрирует синтаксис асинхронных функций. Теперь давайте перейдем к реальным примерам.</p> +<p>Конечно, на практике код выше бесполезен, но в учебных целях он иллюстрирует синтаксис асинхронных функций. Теперь давайте перейдём к реальным примерам.</p> <h2 id="Переписываем_Promises_с_использованием_asyncawait">Переписываем Promises с использованием async/await</h2> @@ -154,7 +154,7 @@ myFetch().then((blob) => { <h3 id="Минуточку_а_как_это_все_работает">Минуточку, а как это все работает ?</h3> -<p>Вы могли заметить, что мы обернули наш код в функцию и сделали ее асинхронной с помощью acync. Это было обязательно - нам надо создать контейнер, внутри которого будет запускаться асинхронный код и будет возможность дождаться его результата с помощью await, не блокируя остальной код нашего скрипта.</p> +<p>Вы могли заметить, что мы обернули наш код в функцию и сделали её асинхронной с помощью acync. Это было обязательно - нам надо создать контейнер, внутри которого будет запускаться асинхронный код и будет возможность дождаться его результата с помощью await, не блокируя остальной код нашего скрипта.</p> <p>Внутри <code>myFetch()</code> находится код, который слегка напоминает версию на Promise, но есть важные отличия. Вместо того, чтобы писать цепочку блоков <code>.then()</code> мы просто использует ключевое слово <code>await</code> перед вызовом promise-based функции и присваиваем результат в переменную. Ключевое слово <code>await</code> говорит JavaScript runtime приостановить код в этой строке, не блокируя остальной код скрипта за пределами асинхронной функции. Когда вызов promise-based функции будет готов вернуть результат, выполнение продолжится с этой строки дальше.<br> <br> @@ -162,7 +162,7 @@ myFetch().then((blob) => { <pre class="brush: js notranslate">let response = await fetch('coffee.jpg');</pre> -<p>Значение Promise, которое вернет <code>fetch()</code> будет присвоено переменной <code>response</code> только тогда, когда оно будет доступно - парсер делает паузу на данной строке дожидаясь этого момента. Как только значение доступно, парсер переходит к следующей строке, в которой создается объект <code><a href="/en-US/docs/Web/API/Blob">Blob</a></code> из результата Promise. В этой строке, кстати, также используется <code>await</code>, потому что метод <code>.blob()</code> также возвращает Promise. Когда результат готов, мы возвращаем его наружу из <code>myFetch()</code>.</p> +<p>Значение Promise, которое вернёт <code>fetch()</code> будет присвоено переменной <code>response</code> только тогда, когда оно будет доступно - парсер делает паузу на данной строке дожидаясь этого момента. Как только значение доступно, парсер переходит к следующей строке, в которой создаётся объект <code><a href="/en-US/docs/Web/API/Blob">Blob</a></code> из результата Promise. В этой строке, кстати, также используется <code>await</code>, потому что метод <code>.blob()</code> также возвращает Promise. Когда результат готов, мы возвращаем его наружу из <code>myFetch()</code>.</p> <p>Обратите внимание, когда мы вызываем <code>myFetch()</code>, она возвращает Promise, поэтому мы можем вызвать <code>.then()</code> на результате, чтобы отобразить его на экране.<br> <br> @@ -173,7 +173,7 @@ myFetch().then((blob) => { <p><br> Чтобы обработать ошибки у нас есть несколько вариантов</p> -<p>Мы можем использовать синхронную <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/try...catch">try...catch</a></code> структуру с <code>async</code>/<code>await</code>. Вот измененная версия первого примера выше:</p> +<p>Мы можем использовать синхронную <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/try...catch">try...catch</a></code> структуру с <code>async</code>/<code>await</code>. Вот изменённая версия первого примера выше:</p> <pre class="brush: js notranslate">async function myFetch() { try { @@ -195,7 +195,7 @@ myFetch().then((blob) => { myFetch();</pre> -<p>В блок <code>catch() {}</code> передается объект ошибки, который мы назвали <code>e</code>; мы можем вывести его в консоль, чтобы посмотреть детали: где и почему возникла ошибка.</p> +<p>В блок <code>catch() {}</code> передаётся объект ошибки, который мы назвали <code>e</code>; мы можем вывести его в консоль, чтобы посмотреть детали: где и почему возникла ошибка.</p> <p>Если вы хотите использовать гибридный подходы (пример выше), лучше использовать блок <code>.catch()</code> после блока <code>.then()</code> вот так:</p> @@ -229,7 +229,7 @@ myFetch().then((blob) => { <h2 id="Await_и_Promise.all">Await и Promise.all()</h2> -<p>Как вы помните, асинхронные функции построены поверх <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">promises</a>, поэтому они совместимы со всеми возможностями последних. Мы легко можем подождать выполнение <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all">Promise.all()</a></code>, присвоить результат в переменную и все это сделать используя синхронный стиль. Опять, вернемся к <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/promises/promise-all.html">примеру, рассмотренному в предыдущей статье</a>. Откройте пример в соседней вкладке, чтобы лучше понять разницу.</p> +<p>Как вы помните, асинхронные функции построены поверх <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">promises</a>, поэтому они совместимы со всеми возможностями последних. Мы легко можем подождать выполнение <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all">Promise.all()</a></code>, присвоить результат в переменную и все это сделать используя синхронный стиль. Опять, вернёмся к <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/promises/promise-all.html">примеру, рассмотренному в предыдущей статье</a>. Откройте пример в соседней вкладке, чтобы лучше понять разницу.</p> <p>Версия с async/await (смотрите <a href="https://mdn.github.io/learning-area/javascript/asynchronous/async-await/promise-all-async-await.html">live demo</a> и <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/async-await/promise-all-async-await.html">source code</a>), сейчас выглядит так:</p> @@ -284,9 +284,9 @@ displayContent() <pre class="brush: js notranslate">let values = await Promise.all([coffee, tea, description]);</pre> -<p>С помощью <code>await</code> мы ждем массив результатов всех трех Promises и присваиваем его в переменную <code>values</code>. Это асинхронный код, но он написан в синхронном стиле, за счет чего он гораздо читабельнее.<br> +<p>С помощью <code>await</code> мы ждём массив результатов всех трёх Promises и присваиваем его в переменную <code>values</code>. Это асинхронный код, но он написан в синхронном стиле, за счёт чего он гораздо читабельнее.<br> <br> - Мы должны обернуть весь код в синхронную функцию, <code>displayContent()</code>, и мы не сильно сэкономили на количестве кода, но мы извлекли код блока <code>.then()</code>, за счет чего наш код стал гораздо чище.</p> + Мы должны обернуть весь код в синхронную функцию, <code>displayContent()</code>, и мы не сильно сэкономили на количестве кода, но мы извлекли код блока <code>.then()</code>, за счёт чего наш код стал гораздо чище.</p> <p>Для обработки ошибок мы добавили блок <code>.catch()</code> для функции <code>displayContent()</code>; Это позволило нам отловить ошибки в обоих функциях.</p> @@ -300,7 +300,7 @@ displayContent() <p>Async/await позволяет вам писать код в синхронном стиле. Ключевое слово <code>await</code> блокирует приостанавливает выполнение ptomise-based функции до того момента, пока promise примет статус fulfilled. Это не блокирует код за пределами вашей асинхронной функции, тем не менее важно помнить, что внутри асинхронной функции поток выполнения блокируется.<br> <br> - Ваш код может стать медленнее за счет большого количества awaited promises, которые идут один за другим. Каждый <code>await</code> должен дождаться выполнения предыдущего, тогда как на самом деле мы хотим, чтобы наши Promises выполнялись одновременно, как если бы мы не использовали async/await.<br> + Ваш код может стать медленнее за счёт большого количества awaited promises, которые идут один за другим. Каждый <code>await</code> должен дождаться выполнения предыдущего, тогда как на самом деле мы хотим, чтобы наши Promises выполнялись одновременно, как если бы мы не использовали async/await.<br> <br> Есть подход, который позволяет обойти эту проблему - сохранить все выполняющиеся Promises в переменные, а уже после этого дожидаться (awaiting) их результата. Давайте посмотрим на несколько примеров.</p> @@ -339,7 +339,7 @@ timeTest().then(() => { await timeoutPromise(3000); }</pre> -<p>Здесь мы просто ждем все три <code>timeoutPromise()</code> напрямую, блокируя выполнение на данного блока на 3 секунды при каждом вызове. Все последующие вызовы вынуждены ждать пока разрешится предыдущий. Если вы запустите первый пример (<code>slow-async-await.html</code>) вы увидите alert сообщающий время выполнения около 9 секунд. </p> +<p>Здесь мы просто ждём все три <code>timeoutPromise()</code> напрямую, блокируя выполнение на данного блока на 3 секунды при каждом вызове. Все последующие вызовы вынуждены ждать пока разрешится предыдущий. Если вы запустите первый пример (<code>slow-async-await.html</code>) вы увидите alert сообщающий время выполнения около 9 секунд. </p> <p>Во втором <code>fast-async-await.html</code> примере, функция <code>timeTest()</code> выглядит как:</p> diff --git a/files/ru/learn/javascript/asynchronous/concepts/index.html b/files/ru/learn/javascript/asynchronous/concepts/index.html index def7da8a78..cd87899ec3 100644 --- a/files/ru/learn/javascript/asynchronous/concepts/index.html +++ b/files/ru/learn/javascript/asynchronous/concepts/index.html @@ -29,7 +29,7 @@ translation_of: Learn/JavaScript/Asynchronous/Concepts <h2 id="Что_же_такое_Асинхронность">Что же такое Асинхронность?</h2> -<p>Как правило, программный код выполняется последовательно, только одна конкретная операция происходит в данный момент времени. Если функция зависит от результата выполнения другой функции, то она должна дождаться пока нужная ей функция не завершит свою работу и не вернет результат и до тех пор пока это не произойдет, выполнение программы, по сути, будет остановлено с точки зрения пользователя.</p> +<p>Как правило, программный код выполняется последовательно, только одна конкретная операция происходит в данный момент времени. Если функция зависит от результата выполнения другой функции, то она должна дождаться пока нужная ей функция не завершит свою работу и не вернёт результат и до тех пор пока это не произойдёт, выполнение программы, по сути, будет остановлено с точки зрения пользователя.</p> <p>Пользователь современного ПК, наверняка, наблюдал, как курсор меняет свой вид и становится "разноцветным спинером" (у пользователей MacOS). Таким образом операционная система сообщает - "текущая программа, ожидает завершения какого то длительного процесса в системе и я решила сообщить тебе, что бы ты не волновался".</p> @@ -43,7 +43,7 @@ translation_of: Learn/JavaScript/Asynchronous/Concepts <p>Давайте рассмотрим несколько примеров, которые покажут, что именно значит <strong>блокировка</strong>.</p> -<p>В нашем <a href="https://github.com/mdn/learning-area/tree/master/javascript/asynchronous/introducing">simple-sync.html</a> примере (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/introducing/simple-sync.html">see it running live</a>), добавим кнопке событие на клик, чтобы при нажатии на нее запускалась трудоемкая операция (расчет 10000000 дат, и вывод последней рассчитанной даты на консоль) после чего в DOM добавляется еще один параграф:</p> +<p>В нашем <a href="https://github.com/mdn/learning-area/tree/master/javascript/asynchronous/introducing">simple-sync.html</a> примере (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/introducing/simple-sync.html">see it running live</a>), добавим кнопке событие на клик, чтобы при нажатии на неё запускалась трудоёмкая операция (расчёт 10000000 дат, и вывод последней рассчитанной даты на консоль) после чего в DOM добавляется ещё один параграф:</p> <pre class="brush: js notranslate">const btn = document.querySelector('button'); btn.addEventListener('click', () => { @@ -69,7 +69,7 @@ btn.addEventListener('click', () => { <p>В нашем следующем примере, <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/introducing/simple-sync-ui-blocking.html">simple-sync-ui-blocking.html</a> (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/introducing/simple-sync-ui-blocking.html">посмотреть пример</a>), мы сделаем что-нибудь более реалистичное, с чем вы сможете столкнуться на реальной странице. Мы заблокируем действия пользователя отрисовкой страницы. В этом примере у нас две кнопки:</p> <ul> - <li>Кнопка "Fill canvas", если на нее кликнуть, рисует в элементе + <li>Кнопка "Fill canvas", если на неё кликнуть, рисует в элементе <div>{{htmlelement("canvas")}}</div> миллион синих кругов.</li> <li>Кнопка "Click me for alert", при нажатии показывает предупреждение.</li> @@ -90,10 +90,10 @@ alertBtn.addEventListener('click', () => alert('You clicked me!') );</pre> -<p>Если вы быстро нажмете на первую кнопку и затем быстро кликните на вторую, вы увидите, что предупреждение не появится на странице, пока все круги не будут отрисованы. Первая операция блокирует выполнение следующей до тех пор пока не завершится сама.</p> +<p>Если вы быстро нажмёте на первую кнопку и затем быстро кликните на вторую, вы увидите, что предупреждение не появится на странице, пока все круги не будут отрисованы. Первая операция блокирует выполнение следующей до тех пор пока не завершится сама.</p> <div class="blockIndicator note"> -<p><strong>Примечание</strong>: Хорошо, в приведенном некрасивом примере, мы получили эффект блокировки, который показывает общую проблему при разработке приложений, с которой все время приходится бороться разработчикам.</p> +<p><strong>Примечание</strong>: Хорошо, в приведённом некрасивом примере, мы получили эффект блокировки, который показывает общую проблему при разработке приложений, с которой все время приходится бороться разработчикам.</p> </div> <p>Почему так происходит? Потому что JavaScript, в общем случае, выполняет команды в <strong>одном потоке</strong>. Пришло время познакомиться с понятием <strong>потока</strong>.</p> @@ -117,7 +117,7 @@ Thread 2: Task C --> Task D</pre> <pre class="notranslate">Main thread: Render circles to canvas --> Display alert()</pre> -<p>В итоге, JavaScript получил несколько инструментов, которые могут помочь в решении подобных проблем. <a href="/en-US/docs/Web/API/Web_Workers_API">Web workers</a> позволяют вам обработать некоторый JavaScript код в отдельном потоке, который называется обработчик, таким образом вы можете запускать отдельные блоки JavaScript кода одновременно. В основном, вы будете использовать воркеры, чтобы запустить ресурсоемкий процесс, отдельно от основного потока, чтобы не блокировать действия пользователя.</p> +<p>В итоге, JavaScript получил несколько инструментов, которые могут помочь в решении подобных проблем. <a href="/en-US/docs/Web/API/Web_Workers_API">Web workers</a> позволяют вам обработать некоторый JavaScript код в отдельном потоке, который называется обработчик, таким образом вы можете запускать отдельные блоки JavaScript кода одновременно. В основном, вы будете использовать воркеры, чтобы запустить ресурсоёмкий процесс, отдельно от основного потока, чтобы не блокировать действия пользователя.</p> <pre class="notranslate"> Main thread: Task A --> Task C Worker thread: Expensive task B</pre> @@ -128,18 +128,18 @@ Worker thread: Expensive task B</pre> <p>Воркеры полезный инструмент, но у них есть свои ограничения. Самое существенное, заключается в том, что они не имеют доступа к {{Glossary("DOM")}} — вы не можете использовать воркер для обновления UI. Мы не можем отрисовать миллион наших точек внутри воркера; он может только обработать большой объем информации.</p> -<p>Следующая проблема заключается в том, что даже если код запущенный в воркере ничего не блокирует, он в целом остается синхронным. Это проблема появляется, когда какой-то функции требуются результаты выполнения нескольких предыдущих функций. Рассмотрим следующую диаграмму потоков:</p> +<p>Следующая проблема заключается в том, что даже если код запущенный в воркере ничего не блокирует, он в целом остаётся синхронным. Это проблема появляется, когда какой-то функции требуются результаты выполнения нескольких предыдущих функций. Рассмотрим следующую диаграмму потоков:</p> <pre class="notranslate">Main thread: Task A --> Task B</pre> -<p>В этом примере, предположим Task A делает что-то вроде получения картинки с сервера а Task B затем делает что-нибудь с полученной картинкой, например, применяет к ней фильтр. Если запустить выполняться Task A и тут же попытаться выполнить Task B, то вы получите ошибку, поскольку картинка еще не будет доступна.</p> +<p>В этом примере, предположим Task A делает что-то вроде получения картинки с сервера а Task B затем делает что-нибудь с полученной картинкой, например, применяет к ней фильтр. Если запустить выполняться Task A и тут же попытаться выполнить Task B, то вы получите ошибку, поскольку картинка ещё не будет доступна.</p> <pre class="notranslate"> Main thread: Task A --> Task B --> |Task D| Worker thread: Task C -----------> | |</pre> -<p>Теперь, давайте предположим, что Task D использует результат выполнения обеих задач Task B и Task C. Если мы уверенны, что оба результата будут доступны одновременно, тогда не возникнет проблем, однако, часто это не так. Если Task D попытаться запустить, когда какого-то нужного ей результата еще нет, выполнение закончится ошибкой.</p> +<p>Теперь, давайте предположим, что Task D использует результат выполнения обеих задач Task B и Task C. Если мы уверенны, что оба результата будут доступны одновременно, тогда не возникнет проблем, однако, часто это не так. Если Task D попытаться запустить, когда какого-то нужного ей результата ещё нет, выполнение закончится ошибкой.</p> -<p>Чтобы избежать подобных проблем, браузеры позволяют нам выполнять определенные операции асинхронно. Такие возможности, как <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promises</a> позволяют запустить некоторую операцию (например, получение картинки с сервера), и затем подождать пока операция не вернет результат, перед тем как начать выполнение другой задачи:</p> +<p>Чтобы избежать подобных проблем, браузеры позволяют нам выполнять определённые операции асинхронно. Такие возможности, как <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promises</a> позволяют запустить некоторую операцию (например, получение картинки с сервера), и затем подождать пока операция не вернёт результат, перед тем как начать выполнение другой задачи:</p> <pre class="notranslate">Main thread: Task A Task B Promise: |__async operation__|</pre> @@ -150,7 +150,7 @@ Worker thread: Task C -----------> | |</pre> <h2 id="Заключение">Заключение</h2> -<p>При проектировании современных программ все больше используется асинхронное программирование, чтобы программа имела возможность выполнять несколько операций в конкретный момент времени. Как только вы начнете использовать новые, более мощные возможности API, вы обнаружите множество ситуаций, где решить нужную задачу можно только асинхронно. Раньше было сложно писать асинхронный код. До сих пор, нужно время, чтобы привыкнуть к такому подходу, но процесс стал намного легче. Далее, в этом разделе, мы будем глубже исследовать вопрос, когда же асинхронный код необходим и как спроектировать программу, чтобы избежать проблем, описанных выше.</p> +<p>При проектировании современных программ все больше используется асинхронное программирование, чтобы программа имела возможность выполнять несколько операций в конкретный момент времени. Как только вы начнёте использовать новые, более мощные возможности API, вы обнаружите множество ситуаций, где решить нужную задачу можно только асинхронно. Раньше было сложно писать асинхронный код. До сих пор, нужно время, чтобы привыкнуть к такому подходу, но процесс стал намного легче. Далее, в этом разделе, мы будем глубже исследовать вопрос, когда же асинхронный код необходим и как спроектировать программу, чтобы избежать проблем, описанных выше.</p> <h2 id="В_этом_модуле">В этом модуле</h2> diff --git a/files/ru/learn/javascript/asynchronous/introducing/index.html b/files/ru/learn/javascript/asynchronous/introducing/index.html index 75cae85c11..731c40dfa7 100644 --- a/files/ru/learn/javascript/asynchronous/introducing/index.html +++ b/files/ru/learn/javascript/asynchronous/introducing/index.html @@ -84,13 +84,13 @@ btn.addEventListener('click', () => { let blob = response.blob(); // display your image blob in the UI somehow</pre> -<p>Это происходит потому что вы не знаете сколько времени займет загрузка картинки, следовательно, когда вы начнёте выполнять вторую строку кода, сгенерируется ошибка (возможно, периодически, возможно, каждый раз), потому что <font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);">response</span></font> еще не доступен. Вместо этого, ваш код должен дождаться возвращения <font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);">response</span></font> до того, как попытается выполнить дальнейшие инструкции.</p> +<p>Это происходит потому что вы не знаете сколько времени займёт загрузка картинки, следовательно, когда вы начнёте выполнять вторую строку кода, сгенерируется ошибка (возможно, периодически, возможно, каждый раз), потому что <font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);">response</span></font> ещё не доступен. Вместо этого, ваш код должен дождаться возвращения <font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);">response</span></font> до того, как попытается выполнить дальнейшие инструкции.</p> -<p>Есть два типа стиля асинхронного кода, с которыми вы столкнетесь в коде JavaScript, старый метод — callbacks (колбэки) и более новый — promise (промисы, обещания). В следующих разделах мы познакомимся с каждым из них. </p> +<p>Есть два типа стиля асинхронного кода, с которыми вы столкнётесь в коде JavaScript, старый метод — callbacks (колбэки) и более новый — promise (промисы, обещания). В следующих разделах мы познакомимся с каждым из них. </p> <h2 id="Асинхронные_колбэки">Асинхронные колбэки</h2> -<p>Асинхронные колбэки — это функции, которые определяются как аргументы при вызове функции, которая начнет выполнение кода на заднем фоне. Когда код на заднем фоне завершает свою работу, он вызывает колбэк-функцию, оповещающую, что работа сделана, либо оповещающую о трудностях в завершении работы. Обратные вызовы — немного устаревшая практика, но они все еще употребляются в некоторых старомодных, но часто используемых API.</p> +<p>Асинхронные колбэки — это функции, которые определяются как аргументы при вызове функции, которая начнёт выполнение кода на заднем фоне. Когда код на заднем фоне завершает свою работу, он вызывает колбэк-функцию, оповещающую, что работа сделана, либо оповещающую о трудностях в завершении работы. Обратные вызовы — немного устаревшая практика, но они все ещё употребляются в некоторых старомодных, но часто используемых API.</p> <p>Пример асинхронного колбэка вторым параметром {{domxref("EventTarget.addEventListener", "addEventListener()")}} (как мы видели выше):</p> @@ -104,9 +104,9 @@ let blob = response.blob(); <p>Первый параметр — тип обрабатываемого события, второй параметр — колбэк-функция, вызываемая при срабатывании события.</p> -<p>При передаче колбэк-функции как аргумента в другую функцию, мы передаем только ссылку на функцию как аргумент, следовательно колбэк-функция <strong>не</strong> выполняется мгновенно. Она вызывается асинхронно внутри тела, содержащего функцию. Эта функция должна выполнять колбэк-функцию в нужный момент.</p> +<p>При передаче колбэк-функции как аргумента в другую функцию, мы передаём только ссылку на функцию как аргумент, следовательно колбэк-функция <strong>не</strong> выполняется мгновенно. Она вызывается асинхронно внутри тела, содержащего функцию. Эта функция должна выполнять колбэк-функцию в нужный момент.</p> -<p>Вы можете написать свою собственную функцию, содержащую колбэк-функцию. Давайте взглянем на еще один пример, в котором происходит загрузка ресурсов через <a href="/en-US/docs/Web/API/XMLHttpRequest"><code>XMLHttpRequest</code> API</a> (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/introducing/xhr-async-callback.html">запустите пример</a>, и <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/introducing/xhr-async-callback.html">посмотрите исходный код</a>):</p> +<p>Вы можете написать свою собственную функцию, содержащую колбэк-функцию. Давайте взглянем на ещё один пример, в котором происходит загрузка ресурсов через <a href="/en-US/docs/Web/API/XMLHttpRequest"><code>XMLHttpRequest</code> API</a> (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/introducing/xhr-async-callback.html">запустите пример</a>, и <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/introducing/xhr-async-callback.html">посмотрите исходный код</a>):</p> <pre class="brush: js notranslate">function loadAsset(url, type, callback) { let xhr = new XMLHttpRequest(); @@ -130,7 +130,7 @@ function displayImage(blob) { loadAsset('coffee.jpg', 'blob', displayImage);</pre> -<p>Мы создали функцию <code>displayImage()</code>, которая представляет blob, переданный в нее, как объект URL, и создает картинку, в которой отображается URL, добавляя ее в элемент документа <code><body></code>. Однако, далее мы создаем функцию <code>loadAsset()</code>, которая принимает колбэк-функцию в качестве параметра, вместе с URL для получения данных и типом контента. Для получения данных из URL используется <code>XMLHttpRequest</code> (часто сокращается до аббревиатуры "XHR") , перед тем как передать ответ в колбэк-функцию для дальнейшей обработки. В этом случае колбэк-функция ждет, пока XHR закончит загрузку данных (используя обработчик события <code><a href="/en-US/docs/Web/API/XMLHttpRequestEventTarget/onload">onload</a></code>) перед отправкой данных в колбэк-функцию.</p> +<p>Мы создали функцию <code>displayImage()</code>, которая представляет blob, переданный в неё, как объект URL, и создаёт картинку, в которой отображается URL, добавляя её в элемент документа <code><body></code>. Однако, далее мы создаём функцию <code>loadAsset()</code>, которая принимает колбэк-функцию в качестве параметра, вместе с URL для получения данных и типом контента. Для получения данных из URL используется <code>XMLHttpRequest</code> (часто сокращается до аббревиатуры "XHR") , перед тем как передать ответ в колбэк-функцию для дальнейшей обработки. В этом случае колбэк-функция ждёт, пока XHR закончит загрузку данных (используя обработчик события <code><a href="/en-US/docs/Web/API/XMLHttpRequestEventTarget/onload">onload</a></code>) перед отправкой данных в колбэк-функцию.</p> <p>Колбэк-функции универсальны — они не только позволяют вам контролировать порядок, в котором запускаются функции и данные, передающиеся между ними, они также позволяют передавать данные различным функциям, в зависимости от обстоятельств. Вы можете выполнять различные действия с загруженным ответом, такие как <code>processJSON()</code>, <code>displayText()</code>, и другие.</p> @@ -163,7 +163,7 @@ gods.forEach(function (eachName, index){ <p>В примере видно, как <code>fetch()</code> принимает один параметр — URL ресурса, который нужно получить из сети, — и возвращает <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">промис</a>. Промис или обещание — это объект, представляющий асинхронную операцию, выполненную удачно или неудачно. Он представляет собой как бы промежуточное состояние. По сути, это способ браузера сказать: "я обещаю вернуться к вам с ответом как можно скорее," отсюда и название "обещание."</p> -<p>Может понадобиться много времени, чтобы привыкнуть к данной концепции; это немного напоминает {{interwiki("wikipedia", "Кот Шрёдингера")}} в действии. Ни один из возможных результатов еще не произошел, поэтому операция fetch в настоящее время ожидает результата. Далее у нас есть три блока кода следующих сразу после <code>fetch()</code>:</p> +<p>Может понадобиться много времени, чтобы привыкнуть к данной концепции; это немного напоминает {{interwiki("wikipedia", "Кот Шрёдингера")}} в действии. Ни один из возможных результатов ещё не произошёл, поэтому операция fetch в настоящее время ожидает результата. Далее у нас есть три блока кода следующих сразу после <code>fetch()</code>:</p> <ul> <li>Два <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then">then()</a></code> блока. Оба включают в себя функцию обратного, которая запустится, если предыдущая операция закончилась успешно, и каждая колбэк-функция принимает на вход результат предыдущей успешно выполненной операции, таким образом вы можете выполнять операции последовательно. Каждый <code>.then()</code> блок возвращает новый promise, это значит что вы можете объединять в цепочки блоки <code>.then()</code>, таким образом можно выполнить несколько асинхронных операций по порядку, одну за другой.</li> @@ -212,9 +212,9 @@ fetch('coffee.jpg').then((response) => { console.log ('All done!');</pre> -<p>Браузер начнет выполнение кода, увидит первый консольный оператор <code>(Starting)</code> и выполнит его, а затем создаст переменную <code>image</code>.</p> +<p>Браузер начнёт выполнение кода, увидит первый консольный оператор <code>(Starting)</code> и выполнит его, а затем создаст переменную <code>image</code>.</p> -<p>Затем он переместится на следующую строку и начнет выполнять блок <code>fetch ()</code>, но, поскольку <code>fetch ()</code> выполняется асинхронно без блокировки, выполнение кода продолжается после кода, связанного с промисом, тем самым достигая окончательного оператора (<code>All done!</code>) и выводя его на консоль.</p> +<p>Затем он переместится на следующую строку и начнёт выполнять блок <code>fetch ()</code>, но, поскольку <code>fetch ()</code> выполняется асинхронно без блокировки, выполнение кода продолжается после кода, связанного с промисом, тем самым достигая окончательного оператора (<code>All done!</code>) и выводя его на консоль.</p> <p>Только после того, как блок <code>fetch ()</code> полностью завершит работу и доставит свой результат через блоки <code>.then ()</code>, мы наконец увидим второе сообщение <code>console.log ()</code> (<code>It worked ;)</code>). Таким образом, сообщения появились не в том порядке, который вы могли ожидать:</p> @@ -234,9 +234,9 @@ button.addEventListener('click', () => { console.log("all done");</pre> -<p>Этот пример очень схож с предыдущим в своем поведении — первое и третье сообщения <code>console.log ()</code> будут показаны немедленно, но второе будет заблокировано, пока кто-то не нажмет кнопку мыши. Предыдущий пример работает аналогичным образом, за исключением того, что в этом случае второе сообщение блокируется цепочкой промисов, получая ресурс, а затем отображая его на экране, а не щелчком мыши.</p> +<p>Этот пример очень схож с предыдущим в своём поведении — первое и третье сообщения <code>console.log ()</code> будут показаны немедленно, но второе будет заблокировано, пока кто-то не нажмёт кнопку мыши. Предыдущий пример работает аналогичным образом, за исключением того, что в этом случае второе сообщение блокируется цепочкой промисов, получая ресурс, а затем отображая его на экране, а не щелчком мыши.</p> -<p>В менее простом примере кода такая система может вызвать проблему — вы не можете включить блок асинхронного кода, который возвращает результат, на который вы потом будете полагаться в блоке синхронного кода. Вы просто не можете гарантировать, что асинхронная функция вернется до того, как браузер обработает синхронный блок.</p> +<p>В менее простом примере кода такая система может вызвать проблему — вы не можете включить блок асинхронного кода, который возвращает результат, на который вы потом будете полагаться в блоке синхронного кода. Вы просто не можете гарантировать, что асинхронная функция вернётся до того, как браузер обработает синхронный блок.</p> <p>Чтобы увидеть это в действии, попробуйте взять локальную копию нашего <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/introducing/async-sync.html">примера</a> и измените третий вызов <code>console.log ()</code> следующим образом:</p> @@ -246,7 +246,7 @@ console.log("all done");</pre> <pre class="notranslate"><span class="message-body-wrapper"><span class="message-flex-body"><span class="devtools-monospace message-body">TypeError: image is undefined; can't access its "src" property</span></span></span></pre> -<p>Это происходит потому, что в то же время браузер пытается запустить третий <code>console.log()</code>, блок <code>fetch()</code> еще не закончил выполнение, поэтому переменная <code>image</code> еще не имеет значения.</p> +<p>Это происходит потому, что в то же время браузер пытается запустить третий <code>console.log()</code>, блок <code>fetch()</code> ещё не закончил выполнение, поэтому переменная <code>image</code> ещё не имеет значения.</p> <div class="blockIndicator note"> <p><strong>Заметка</strong>: Из соображений безопасности вы не можете применять <code>fetch() </code> к файлам из вашей локальной системы (или запустить другие такие операции локально); чтобы запустить локально пример выше вам необходимо запустить его через <a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/Common_questions/set_up_a_local_testing_server">локальный веб-сервер</a>.</p> @@ -254,7 +254,7 @@ console.log("all done");</pre> <h2 id="Активное_обучение_сделайте_все_это_асинхронно!">Активное обучение: сделайте все это асинхронно!</h2> -<p>Чтобы исправить проблемный пример с <code>fetch()</code> и заставить все три сообщения <code>console.log()</code> появиться в желаемом порядке, вы можете также запустить третье сообщение <code>console.log()</code> асинхронно. Этого можно добиться, переместив его внутрь другого блока <code>.then()</code> присоединенного к концу второго, или просто переместив его внутрь второго блока <code>then()</code>. Попробуйте исправить это сейчас..</p> +<p>Чтобы исправить проблемный пример с <code>fetch()</code> и заставить все три сообщения <code>console.log()</code> появиться в желаемом порядке, вы можете также запустить третье сообщение <code>console.log()</code> асинхронно. Этого можно добиться, переместив его внутрь другого блока <code>.then()</code> присоединённого к концу второго, или просто переместив его внутрь второго блока <code>then()</code>. Попробуйте исправить это сейчас..</p> <div class="blockIndicator note"> <p><strong>Заметка</strong>: Если вы застряли, вы можете <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/introducing/async-sync-fixed.html">найти ответ здесь</a> (также можно посмотреть <a href="https://mdn.github.io/learning-area/javascript/asynchronous/introducing/async-sync-fixed.html">запущенный пример</a>). Также вы можете найти много информации о промисах в нашем гайде <a href="/en-US/docs/Learn/JavaScript/Asynchronous/Promises">Основные понятия асинхронного программирования</a> позднее в этом модуле.</p> diff --git a/files/ru/learn/javascript/asynchronous/timeouts_and_intervals/index.html b/files/ru/learn/javascript/asynchronous/timeouts_and_intervals/index.html index 7b8522a964..1db889130a 100644 --- a/files/ru/learn/javascript/asynchronous/timeouts_and_intervals/index.html +++ b/files/ru/learn/javascript/asynchronous/timeouts_and_intervals/index.html @@ -1,5 +1,5 @@ --- -title: 'Объединенный асинхронный JavaScript: Таймауты и интервалы' +title: 'Объединённый асинхронный JavaScript: Таймауты и интервалы' slug: Learn/JavaScript/Asynchronous/Timeouts_and_intervals translation_of: Learn/JavaScript/Asynchronous/Timeouts_and_intervals original_slug: Learn/JavaScript/Asynchronous/Таймауты_и_интервалы @@ -25,7 +25,7 @@ original_slug: Learn/JavaScript/Asynchronous/Таймауты_и_интерва <h2 id="Введение">Введение</h2> -<p>В течение долгого времени веб-платформа предлагала программистам JavaScript ряд функций, которые позволяли им асинхронно выполнять код по истечении определенного временного интервала и повторно выполнять асинхронный блок кода, пока вы не скажете ему остановиться.</p> +<p>В течение долгого времени веб-платформа предлагала программистам JavaScript ряд функций, которые позволяли им асинхронно выполнять код по истечении определённого временного интервала и повторно выполнять асинхронный блок кода, пока вы не скажете ему остановиться.</p> <p>Эти функции:</p> @@ -33,7 +33,7 @@ original_slug: Learn/JavaScript/Asynchronous/Таймауты_и_интерва <dt><code><a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout">setTimeout()</a></code></dt> <dd>Выполняет указанный блок кода один раз по истечении указанного времени</dd> <dt><code><a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval">setInterval()</a></code></dt> - <dd>Выполняет указанный блок кода несколько раз с определенным интервалом между каждым вызовом.</dd> + <dd>Выполняет указанный блок кода несколько раз с определённым интервалом между каждым вызовом.</dd> <dt><code><a href="/en-US/docs/Web/API/window/requestAnimationFrame">requestAnimationFrame()</a></code></dt> <dd>Современная версия setInterval (). Выполняют указанный блок кода перед тем, как браузер в следующий раз перерисовывает отображение, позволяя запускать анимацию с подходящей частотой кадров независимо от среды, в которой она выполняется.</dd> </dl> @@ -41,23 +41,23 @@ original_slug: Learn/JavaScript/Asynchronous/Таймауты_и_интерва <p>Асинхронный код, установленный этими функциями, выполняется в основном потоке (по истечении указанного им таймера).</p> <div> -<p>Важно знать, что вы можете (и часто будете) запускать другой код до выполнения вызова setTimeout () или между итерациями setInterval (). В зависимости от того, насколько интенсивно используются эти операции для процессора, они могут еще больше задержать выполнение асинхронного кода, поскольку любой асинхронный код будет выполняться только после того, как станет доступен основной поток. (Другими словами, когда стек пуст.) Вы узнаете больше по этому вопросу по мере изучения этой статьи.</p> +<p>Важно знать, что вы можете (и часто будете) запускать другой код до выполнения вызова setTimeout () или между итерациями setInterval (). В зависимости от того, насколько интенсивно используются эти операции для процессора, они могут ещё больше задержать выполнение асинхронного кода, поскольку любой асинхронный код будет выполняться только после того, как станет доступен основной поток. (Другими словами, когда стек пуст.) Вы узнаете больше по этому вопросу по мере изучения этой статьи.</p> </div> <p>В любом случае эти функции используются для запуска постоянной анимации и другой фоновой обработки на веб-сайте или в приложении. В следующих разделах мы покажем вам, как их можно использовать.</p> <h2 id="setTimeout">setTimeout()</h2> -<p>Как мы ранее отметили, setTimeout () выполняет определенный блок кода один раз по истечении заданного времени. Принимает следующие параметры:</p> +<p>Как мы ранее отметили, setTimeout () выполняет определённый блок кода один раз по истечении заданного времени. Принимает следующие параметры:</p> <ul> - <li>Функция для запуска или ссылка на функцию, определенную в другом месте.</li> + <li>Функция для запуска или ссылка на функцию, определённую в другом месте.</li> <li>Число, представляющее интервал времени в миллисекундах (1000 миллисекунд равняется 1 секунде) ожидания перед выполнением кода. Если вы укажете значение 0 (или просто опустите значение), функция запустится как можно скорее. (См. Примечание ниже о том, почему он запускается «как можно скорее», а не «сразу».) Подробнее о том, почему вы, возможно, захотите сделать это позже.</li> - <li>Значений, представляющие любые параметры, которые вы хотите передать функции при ее запуске.</li> + <li>Значений, представляющие любые параметры, которые вы хотите передать функции при её запуске.</li> </ul> <div class="blockIndicator note"> -<p><strong>NOTE: </strong> Указанное время (или задержка) не является гарантированным временем выполнения, а скорее минимальным временем выполнения. Обратные вызовы, которые вы передаете этим функциям, не могут выполняться, пока стек в основном потоке не станет пустым.</p> +<p><strong>NOTE: </strong> Указанное время (или задержка) не является гарантированным временем выполнения, а скорее минимальным временем выполнения. Обратные вызовы, которые вы передаёте этим функциям, не могут выполняться, пока стек в основном потоке не станет пустым.</p> <p>Как следствие, такой код, как setTimeout (fn, 0), будет выполняться, как только стек будет пуст, а не сразу. Если вы выполните такой код, как setTimeout (fn, 0), но сразу после выполнения цикла, который насчитывает от 1 до 10 миллиардов, ваш колбэк будет выполнен через несколько секунд.</p> </div> @@ -68,14 +68,14 @@ original_slug: Learn/JavaScript/Asynchronous/Таймауты_и_интерва alert('Hello, Mr. Universe!'); }, 2000)</pre> -<p>Указанные вами функции не обязательно должны быть анонимными. Вы можете дать своей функции имя и даже определить ее где-нибудь еще и передать ссылку на функцию в setTimeout (). Следующие две версии фрагмента кода эквивалентны первой:</p> +<p>Указанные вами функции не обязательно должны быть анонимными. Вы можете дать своей функции имя и даже определить её где-нибудь ещё и передать ссылку на функцию в setTimeout (). Следующие две версии фрагмента кода эквивалентны первой:</p> <pre class="brush: js notranslate">// С именованной функцией let myGreeting = setTimeout(function sayHi() { alert('Hello, Mr. Universe!'); }, 2000) -// С функцией определенной отдельно +// С функцией определённой отдельно function sayHi() { alert('Hello Mr. Universe!'); } @@ -114,9 +114,9 @@ let myGreeting = setTimeout(sayHi, 2000);</pre> <p><code>setTimeout ()</code> отлично работает, когда вам нужно один раз запустить код по истечении заданного периода времени. Но что происходит, когда вам нужно запускать код снова и снова - например, в случае анимации?</p> -<p>Здесь пригодится <a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval">setInterval()</a> . Работает очень похоже на setTimeout (), за исключением того, что функция, которую вы передаете в качестве первого параметра, выполняется повторно не менее чем за количество миллисекунд, заданных вторым параметром. Вы также можете передать любые параметры, необходимые для выполняемой функции, в качестве последующих параметров вызова setInterval ().</p> +<p>Здесь пригодится <a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval">setInterval()</a> . Работает очень похоже на setTimeout (), за исключением того, что функция, которую вы передаёте в качестве первого параметра, выполняется повторно не менее чем за количество миллисекунд, заданных вторым параметром. Вы также можете передать любые параметры, необходимые для выполняемой функции, в качестве последующих параметров вызова setInterval ().</p> -<p>Давайте посмотрим на пример. Следующая функция создает новый объект <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date">Date()</a></code>, с помощью <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleTimeString">toLocaleTimeString()</a></code> извлекает из него строку с временем и отображает ее в пользовательском интерфейсе. Затем он запускает функцию один раз в секунду с помощью <code>setInterval()</code>, создавая эффект цифровых часов, которые обновляются раз в секунду (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/loops-and-intervals/setinterval-clock.html"> реальный пример</a>, и <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/loops-and-intervals/setinterval-clock.html">исходный код</a>):</p> +<p>Давайте посмотрим на пример. Следующая функция создаёт новый объект <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date">Date()</a></code>, с помощью <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleTimeString">toLocaleTimeString()</a></code> извлекает из него строку с временем и отображает её в пользовательском интерфейсе. Затем он запускает функцию один раз в секунду с помощью <code>setInterval()</code>, создавая эффект цифровых часов, которые обновляются раз в секунду (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/loops-and-intervals/setinterval-clock.html"> реальный пример</a>, и <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/loops-and-intervals/setinterval-clock.html">исходный код</a>):</p> <pre class="brush: js notranslate">function displayTime() { let date = new Date(); @@ -126,7 +126,7 @@ let myGreeting = setTimeout(sayHi, 2000);</pre> const createClock = setInterval(displayTime, 1000);</pre> -<p>Как и <code>setTimeout ()</code>, <code>setInterval ()</code> возвращает определенное значение, которое вы можете использовать позже, когда вам нужно очистить интервал.</p> +<p>Как и <code>setTimeout ()</code>, <code>setInterval ()</code> возвращает определённое значение, которое вы можете использовать позже, когда вам нужно очистить интервал.</p> <h3 id="Очистка_интервала">Очистка интервала</h3> @@ -138,14 +138,14 @@ clearInterval(myInterval);</pre> <h4 id="Активное_обучение_Создание_собственного_секундомера!">Активное обучение: Создание собственного секундомера!</h4> -<p>Учитывая все вышесказанное, у нас есть для вас задача. Возьмите копию нашего примера <code><a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/loops-and-intervals/setinterval-clock.html">setInterval-clock.html</a></code> , и измените ее так, чтобы создать свой собственный простой секундомер.</p> +<p>Учитывая все вышесказанное, у нас есть для вас задача. Возьмите копию нашего примера <code><a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/loops-and-intervals/setinterval-clock.html">setInterval-clock.html</a></code> , и измените её так, чтобы создать свой собственный простой секундомер.</p> <p>Вам нужно отображать время, как и раньше, но в этом примере вам нужно:</p> <ul> <li>Кнопка "Start" для запуска секундомера.</li> <li>Кнопка "Stop" для паузы/остановки.</li> - <li>Кнопка "Reset", чтобы сбросить счетчик времени на <code>0</code>.</li> + <li>Кнопка "Reset", чтобы сбросить счётчик времени на <code>0</code>.</li> <li>Дисплей времени, чтобы отображать количество прошедших секунд а не фактическое время.</li> </ul> @@ -155,17 +155,17 @@ clearInterval(myInterval);</pre> <li>Вы можете структурировать и стилизовать разметку кнопок по своему усмотрению; просто убедитесь, что вы используете семантический HTML с кавычками, которые позволяют захватывать ссылки на кнопки с помощью JavaScript.</li> <li>Вероятно, вы захотите создать переменную, которая начинается с 0, а затем увеличивается на единицу каждую секунду с использованием постоянного цикла.</li> <li>Этот пример проще создать без использования объекта Date (), как мы это делали в нашей версии, но он будет менее точен - вы не можете гарантировать, что колбэк сработает ровно через 1000 мс. Более точным способом было бы запустить startTime = Date.now (), чтобы получить метку времени, когда пользователь нажал кнопку запуска, а затем выполнить Date.now () - startTime, чтобы получить количество миллисекунд после того, как была нажата кнопка запуска .</li> - <li>Вам также нужно рассчитать количество часов, минут и секунд как отдельные значения, а затем отображать их вместе в строке после каждой итерации цикла. На втором счетчике вы можете отработать каждую из них.</li> + <li>Вам также нужно рассчитать количество часов, минут и секунд как отдельные значения, а затем отображать их вместе в строке после каждой итерации цикла. На втором счётчике вы можете отработать каждую из них.</li> <li>Как вы могли бы их рассчитать? Подумайте об этом: <ul> <li>В одном часе <code>3600 </code>секунд.</li> - <li>Количество минут - это количество секунд, оставшееся после вычитания всех часов, разделенное на 60.</li> + <li>Количество минут - это количество секунд, оставшееся после вычитания всех часов, разделённое на 60.</li> <li>Количество секунд будет количеством секунд, оставшихся после вычитания всех минут.</li> </ul> </li> <li>Вам необходимо включить начальный ноль в отображаемые значения, если сумма меньше <code>10</code>, чтобы они больше походили на традиционные часы.</li> - <li>Чтобы приостановить секундомер, вам нужно очистить интервал. Чтобы сбросить его, вам нудно установить счетчик обратно на <code>0</code>, очистить интервал, а затем немедленно обновить отображение.</li> - <li>Вероятно, вам следует отключить кнопку запуска после ее нажатия один раз и снова включить ее после того, как вы остановили / сбросили ее. В противном случае многократное нажатие кнопки запуска приведет к применению нескольких <code>setInterval ()</code> к часам, что приведет к неправильному поведению.</li> + <li>Чтобы приостановить секундомер, вам нужно очистить интервал. Чтобы сбросить его, вам нудно установить счётчик обратно на <code>0</code>, очистить интервал, а затем немедленно обновить отображение.</li> + <li>Вероятно, вам следует отключить кнопку запуска после её нажатия один раз и снова включить её после того, как вы остановили / сбросили её. В противном случае многократное нажатие кнопки запуска приведёт к применению нескольких <code>setInterval ()</code> к часам, что приведёт к неправильному поведению.</li> </ul> <div class="blockIndicator note"> @@ -178,9 +178,9 @@ clearInterval(myInterval);</pre> <h3 id="Рекурсивные_таймауты">Рекурсивные таймауты</h3> -<p>Есть еще один способ использования <code>setTimeout ()</code>: вы можете вызвать его рекурсивно для повторного запуска одного и того же кода вместо использования <code>setInterval ()</code>.</p> +<p>Есть ещё один способ использования <code>setTimeout ()</code>: вы можете вызвать его рекурсивно для повторного запуска одного и того же кода вместо использования <code>setInterval ()</code>.</p> -<p>В приведенном ниже примере используется рекурсивный setTimeout () для запуска переданной функции каждые 100 миллисекунд:</p> +<p>В приведённом ниже примере используется рекурсивный setTimeout () для запуска переданной функции каждые 100 миллисекунд:</p> <pre class="brush: js notranslate">let i = 1; @@ -190,7 +190,7 @@ setTimeout(function run() { setTimeout(run, 100); }, 100);</pre> -<p>Сравните приведенный выше пример со следующим - здесь используется <code>setInterval ()</code> для достижения того же эффекта:</p> +<p>Сравните приведённый выше пример со следующим - здесь используется <code>setInterval ()</code> для достижения того же эффекта:</p> <pre class="brush: js notranslate">let i = 1; @@ -201,10 +201,10 @@ setInterval(function run() { <h4 id="Чем_рекурсивный_setTimeout_отличается_от_setInterval">Чем рекурсивный <code>setTimeout ()</code> отличается от <code>setInterval () </code>?</h4> -<p>Разница между двумя версиями приведенного выше кода невелика.</p> +<p>Разница между двумя версиями приведённого выше кода невелика.</p> <ul> - <li>Рекурсивный <code>setTimeout ()</code> гарантирует такую же задержку между выполнениями. (Например, 100 мс в приведенном выше случае.) Код будет запущен, затем подождет 100 миллисекунд, прежде чем запустится снова, поэтому интервал будет одинаковым, независимо от того, сколько времени требуется для выполнения кода.</li> + <li>Рекурсивный <code>setTimeout ()</code> гарантирует такую же задержку между выполнениями. (Например, 100 мс в приведённом выше случае.) Код будет запущен, затем подождёт 100 миллисекунд, прежде чем запустится снова, поэтому интервал будет одинаковым, независимо от того, сколько времени требуется для выполнения кода.</li> <li>Пример с использованием <code>setInterval () </code>работает несколько иначе. Выбранный вами интервал включает время, затрачиваемое на выполнение кода, который вы хотите запустить. Предположим, что выполнение кода занимает <code>40 </code>миллисекунд - тогда интервал составляет всего <code>60 </code>миллисекунд.</li> <li>При рекурсивном использовании <code>setTimeout ()</code> каждая итерация может вычислять различную задержку перед запуском следующей итерации. Другими словами, значение второго параметра может указывать другое время в миллисекундах для ожидания перед повторным запуском кода.</li> </ul> @@ -215,7 +215,7 @@ setInterval(function run() { <p>Использование 0 в качестве значения для <code>setTimeout ()</code> позволяет планировать выполнение указанной колбэк-функции как можно скорее, но только после того, как будет запущен основной поток кода.</p> -<p>Например, код приведенный ниже (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/loops-and-intervals/zero-settimeout.html">рабочий код</a>) выводит alert содержащий <code>"Hello"</code>, затем alert содержащий <code>"World"</code> как только вы нажмете ОК в первом alert.</p> +<p>Например, код приведённый ниже (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/loops-and-intervals/zero-settimeout.html">рабочий код</a>) выводит alert содержащий <code>"Hello"</code>, затем alert содержащий <code>"World"</code> как только вы нажмёте ОК в первом alert.</p> <pre class="brush: js notranslate">setTimeout(function() { alert('World'); @@ -250,7 +250,7 @@ alert('Hello');</pre> draw();</pre> -<p>Идея состоит в том, чтобы определить функцию, в которой ваша анимация обновляется (например, ваши спрайты перемещаются, счет обновляется, данные обновляются или что-то еще). Затем вы вызываете его, чтобы начать процесс. В конце функционального блока вы вызываете <code>requestAnimationFrame ()</code> со ссылкой на функцию, переданной в качестве параметра, и это дает браузеру указание вызвать функцию снова при следующей перерисовке дисплея. Затем он выполняется непрерывно, поскольку код рекурсивно вызывает <code>requestAnimationFrame ().</code></p> +<p>Идея состоит в том, чтобы определить функцию, в которой ваша анимация обновляется (например, ваши спрайты перемещаются, счёт обновляется, данные обновляются или что-то ещё). Затем вы вызываете его, чтобы начать процесс. В конце функционального блока вы вызываете <code>requestAnimationFrame ()</code> со ссылкой на функцию, переданной в качестве параметра, и это даёт браузеру указание вызвать функцию снова при следующей перерисовке дисплея. Затем он выполняется непрерывно, поскольку код рекурсивно вызывает <code>requestAnimationFrame ().</code></p> <div class="blockIndicator note"> <p><strong>Note</strong>: Если вы хотите выполнить простое постоянное анимирование DOM , <a href="/en-US/docs/Web/CSS/CSS_Animations">CSS Анимация</a> вероятно будет быстрее. Она вычисляется непосредственно внутренним кодом браузера, а не JavaScript.</p> @@ -264,13 +264,13 @@ draw();</pre> <p>Поскольку большинство экранов имеют частоту обновления 60 Гц, максимальная частота кадров, к которой вы можете стремиться, составляет 60 кадров в секунду (FPS) при работе с веб-браузерами. Однако большее количество кадров означает больше обработки, которая часто может вызывать заикание и пропуски, также известные как пропадание кадров или заедание.</p> -<p>Если у вас есть монитор с частотой обновления 60 Гц и вы хотите достичь 60 кадров в секунду, у вас есть около 16,7 миллисекунд <code>(1000/60)</code> для выполнения кода анимации для рендеринга каждого кадра. Это напоминание о том, что вам нужно помнить об объеме кода, который вы пытаетесь запустить во время каждого прохождения цикла анимации.</p> +<p>Если у вас есть монитор с частотой обновления 60 Гц и вы хотите достичь 60 кадров в секунду, у вас есть около 16,7 миллисекунд <code>(1000/60)</code> для выполнения кода анимации для рендеринга каждого кадра. Это напоминание о том, что вам нужно помнить об объёме кода, который вы пытаетесь запустить во время каждого прохождения цикла анимации.</p> -<p><code>requestAnimationFrame ()</code> всегда пытается приблизиться к этому волшебному значению 60 FPS, насколько это возможно. Иногда это невозможно - если у вас действительно сложная анимация и вы запускаете ее на медленном компьютере, частота кадров будет меньше. Во всех случаях<code> requestAnimationFrame ()</code> всегда будет делать все возможное с тем, что у него есть.</p> +<p><code>requestAnimationFrame ()</code> всегда пытается приблизиться к этому волшебному значению 60 FPS, насколько это возможно. Иногда это невозможно - если у вас действительно сложная анимация и вы запускаете её на медленном компьютере, частота кадров будет меньше. Во всех случаях<code> requestAnimationFrame ()</code> всегда будет делать все возможное с тем, что у него есть.</p> <h3 id="Чем_отличается_requestAnimationFrame_от_setInterval_and_setTimeout">Чем отличается requestAnimationFrame() от setInterval() and setTimeout()?</h3> -<p>Давайте поговорим еще немного о том, чем метод <code>requestAnimationFrame ()</code> отличается от других методов, используемых ранее. Глядя на наш код сверху:</p> +<p>Давайте поговорим ещё немного о том, чем метод <code>requestAnimationFrame ()</code> отличается от других методов, используемых ранее. Глядя на наш код сверху:</p> <pre class="brush: js notranslate">function draw() { // Drawing code goes here @@ -295,7 +295,7 @@ setInterval(draw, 17);</pre> <p>Фактическому колбэку, переданному в функцию <code>requestAnimationFrame ()</code>, также может быть задан параметр: значение отметки времени, которое представляет время с момента начала работы <code>requestAnimationFrame ().</code></p> -<p>Это полезно, поскольку позволяет запускать вещи в определенное время и в постоянном темпе, независимо от того, насколько быстрым или медленным может быть ваше устройство. Общий шаблон, который вы бы использовали, выглядит примерно так:</p> +<p>Это полезно, поскольку позволяет запускать вещи в определённое время и в постоянном темпе, независимо от того, насколько быстрым или медленным может быть ваше устройство. Общий шаблон, который вы бы использовали, выглядит примерно так:</p> <pre class="brush: js notranslate">let startTime = null; @@ -321,7 +321,7 @@ draw();</pre> <h3 id="Простой_пример">Простой пример</h3> -<p>Хватит теории! Давайте выполним упражнение с использованием <code>requestAnimationFrame()</code> . Создадим простую анимацию "spinner animation"—вы могли ее видеть в приложениях когда происходят задержки при ответе с сервера и т.п..</p> +<p>Хватит теории! Давайте выполним упражнение с использованием <code>requestAnimationFrame()</code> . Создадим простую анимацию "spinner animation"—вы могли её видеть в приложениях когда происходят задержки при ответе с сервера и т.п..</p> <div class="blockIndicator note"> <p><strong>Note</strong>: Для такой простой анимации, вам следовало бы использовать CSS . Однако такой вид анимации очень полезен для демонстрации <code>requestAnimationFrame()</code> , вы скорее всего будете использовать этот метод когда делаете что-то более сложное, например обновление отображения игры в каждом кадре.</p> @@ -376,7 +376,7 @@ let rAF; }</pre> </li> <li> - <p>Внутри <code>draw ()</code> добавьте следующие строки. Они определят время начала, если оно еще не определено (это произойдет только на первой итерации цикла), и установят для параметра <code>rotateCount</code> значение для поворота счетчика (текущая временная метка, возьмите начальную временную метку, разделенную на три, чтобы замедлиться):</p> + <p>Внутри <code>draw ()</code> добавьте следующие строки. Они определят время начала, если оно ещё не определено (это произойдёт только на первой итерации цикла), и установят для параметра <code>rotateCount</code> значение для поворота счётчика (текущая временная метка, возьмите начальную временную метку, разделённую на три, чтобы замедлиться):</p> <pre class="brush: js notranslate"> if (!startTime) { startTime = timestamp; @@ -396,7 +396,7 @@ let rAF; <pre class="brush: js notranslate">spinner.style.transform = `rotate(${rotateCount}deg)`;</pre> </li> <li> - <p>В самом низу внутри функции <em>draw ()</em> вставьте следующую строку. Это ключ ко всей операции - вы устанавливаете для переменной, определенной ранее, активный вызов<em> requestAnimation ()</em>, который принимает функцию <em>draw ()</em> в качестве своего параметра. Это запускает анимацию, постоянно выполняя функцию <em>draw ()</em> со скоростью, близкой к 60 FPS.</p> + <p>В самом низу внутри функции <em>draw ()</em> вставьте следующую строку. Это ключ ко всей операции - вы устанавливаете для переменной, определённой ранее, активный вызов<em> requestAnimation ()</em>, который принимает функцию <em>draw ()</em> в качестве своего параметра. Это запускает анимацию, постоянно выполняя функцию <em>draw ()</em> со скоростью, близкой к 60 FPS.</p> <pre class="brush: js notranslate">rAF = requestAnimationFrame(draw);</pre> </li> @@ -421,13 +421,13 @@ let rAF; <h3 id="Активное_обучение_запуск_и_остановка_нашей_анимации">Активное обучение: запуск и остановка нашей анимации</h3> -<p>В этом упражнении мы хотели бы, чтобы вы протестировали метод <code>cancelAnimationFrame ()</code>, взяв наш предыдущий пример и обновив его, добавив обработчик событий для запуска и остановки счетчика при щелчке мышью в любом месте страницы.</p> +<p>В этом упражнении мы хотели бы, чтобы вы протестировали метод <code>cancelAnimationFrame ()</code>, взяв наш предыдущий пример и обновив его, добавив обработчик событий для запуска и остановки счётчика при щелчке мышью в любом месте страницы.</p> <p>Подсказки:</p> <ul> <li>Обработчик события щелчка можно добавить к большинству элементов, включая документ <code><body></code>. Имеет смысл поместить его в элемент <code><body></code>, если вы хотите максимизировать интерактивную область - событие всплывает до его дочерних элементов.</li> - <li>Вы захотите добавить переменную отслеживания, чтобы проверить, вращается ли счетчик или нет, очистив кадр анимации, если он есть, и снова вызвать его, если это не так.</li> + <li>Вы захотите добавить переменную отслеживания, чтобы проверить, вращается ли счётчик или нет, очистив кадр анимации, если он есть, и снова вызвать его, если это не так.</li> </ul> <div class="blockIndicator note"> @@ -436,9 +436,9 @@ let rAF; <h3 id="Регулировка_анимации_requestAnimationFrame">Регулировка анимации <code>requestAnimationFrame()</code> </h3> -<p>Одним из ограничений <code>requestAnimationFrame ()</code> является то, что вы не можете выбирать частоту кадров. В большинстве случаев это не проблема, так как обычно вы хотите, чтобы ваша анимация работала как можно плавное. Но как насчет того, чтобы создать олдскульную 8-битную анимацию?</p> +<p>Одним из ограничений <code>requestAnimationFrame ()</code> является то, что вы не можете выбирать частоту кадров. В большинстве случаев это не проблема, так как обычно вы хотите, чтобы ваша анимация работала как можно плавное. Но как насчёт того, чтобы создать олдскульную 8-битную анимацию?</p> -<p>Это было проблемой, например в анимации ходьбы, вдохновленной островом обезьян, из статьи <a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Drawing_graphics">Drawing Graphics</a>:</p> +<p>Это было проблемой, например в анимации ходьбы, вдохновлённой островом обезьян, из статьи <a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Drawing_graphics">Drawing Graphics</a>:</p> <p>{{EmbedGHLiveSample("learning-area/javascript/apis/drawing-graphics/loops_animation/7_canvas_walking_animation.html", '100%', 260)}}</p> @@ -466,13 +466,13 @@ let rAF; <p>Это код, который вычисляет, как обновлять позицию в каждом кадре анимации.</p> -<p>Метод, который вы используете для регулирования анимации, будет зависеть от вашего конкретного кода. Например, в предыдущем примере счетчика вы могли заставить его двигаться медленнее, увеличивая rotateCount только на единицу в каждом кадре вместо двух.</p> +<p>Метод, который вы используете для регулирования анимации, будет зависеть от вашего конкретного кода. Например, в предыдущем примере счётчика вы могли заставить его двигаться медленнее, увеличивая rotateCount только на единицу в каждом кадре вместо двух.</p> <h2 id="Активное_обучение_игра_на_реакцию">Активное обучение: игра на реакцию</h2> <p>В последнем разделе этой статьи вы создадите игру на реакцию для двух игроков. В игре будет два игрока, один из которых управляет игрой с помощью клавиши <kbd>A</kbd>, а другой - с помощью клавиши<kbd> L</kbd>.</p> -<p>При нажатии кнопки «Start» счетчик, подобный тому, что мы видели ранее, отображается в течение случайного промежутка времени от 5 до 10 секунд. По истечении этого времени появится сообщение «PLAYERS GO !!» - как только это произойдет, первый игрок, который нажмет свою кнопку управления, выиграет игру.</p> +<p>При нажатии кнопки «Start» счётчик, подобный тому, что мы видели ранее, отображается в течение случайного промежутка времени от 5 до 10 секунд. По истечении этого времени появится сообщение «PLAYERS GO !!» - как только это произойдёт, первый игрок, который нажмёт свою кнопку управления, выиграет игру.</p> <p>{{EmbedGHLiveSample("learning-area/javascript/asynchronous/loops-and-intervals/reaction-game.html", '100%', 500)}}</p> @@ -480,7 +480,7 @@ let rAF; <ol> <li> - <p>Прежде всего, скачайте <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/loops-and-intervals/reaction-game-starter.html">стартовый файл</a>. Он содержит законченную структуру HTML и стили CSS, что дает нам игровую доску, которая показывает информацию двух игроков (как показано выше), но с счетчиком и параграфом результатов, отображаемыми друг над другом. Вам нужно просто написать JavaScript код.</p> + <p>Прежде всего, скачайте <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/loops-and-intervals/reaction-game-starter.html">стартовый файл</a>. Он содержит законченную структуру HTML и стили CSS, что даёт нам игровую доску, которая показывает информацию двух игроков (как показано выше), но с счётчиком и параграфом результатов, отображаемыми друг над другом. Вам нужно просто написать JavaScript код.</p> </li> <li> <p>Внутри пустого элемента {{htmlelement("script")}} на вашей странице, начните с добавления следующих строк кода, которые определяют некоторые переменные и константы, которые вам понадобятся в дальнейшем:</p> @@ -498,8 +498,8 @@ const result = document.querySelector('.result');</pre> <ol> <li>Ссылка на спиннер, чтобы вы могли его анимировать.</li> <li>Ссылка на элемент {{htmlelement("div")}} содержащий спиннер, используемый для отображения и скрытия.</li> - <li>Счетчик поворотов. Он определяет, на сколько вы хотите показывать вращение спиннера на каждом кадре анимации.</li> - <li>Нулевое время начала. Это будет заполнено временем начала, когда счетчик начнет вращаться.</li> + <li>Счётчик поворотов. Он определяет, на сколько вы хотите показывать вращение спиннера на каждом кадре анимации.</li> + <li>Нулевое время начала. Это будет заполнено временем начала, когда счётчик начнёт вращаться.</li> <li>Неинициализированная переменная для последующего хранения вызова {{domxref("Window.requestAnimationFrame", "requestAnimationFrame()")}} который анимирует спиннер.</li> <li>Ссылка на кнопку Start .</li> <li>Ссылка на параграф результатов.</li> @@ -514,7 +514,7 @@ const result = document.querySelector('.result');</pre> }</pre> </li> <li> - <p>Затем добавьте функцию draw(), которая анимирует спиннер. Это очень похоже на версию из предыдущего примера простого счетчика:</p> + <p>Затем добавьте функцию draw(), которая анимирует спиннер. Это очень похоже на версию из предыдущего примера простого счётчика:</p> <pre class="brush: js notranslate">function draw(timestamp) { if(!startTime) { @@ -532,13 +532,13 @@ const result = document.querySelector('.result');</pre> }</pre> </li> <li> - <p>Теперь пришло время настроить начальное состояние приложения при первой загрузке страницы. Добавьте следующие две строки, которые просто скрывают абзац результатов и контейнер счетчика с помощью <code>display: none</code> ;.</p> + <p>Теперь пришло время настроить начальное состояние приложения при первой загрузке страницы. Добавьте следующие две строки, которые просто скрывают абзац результатов и контейнер счётчика с помощью <code>display: none</code> ;.</p> <pre class="brush: js notranslate">result.style.display = 'none'; spinnerContainer.style.display = 'none';</pre> </li> <li> - <p>Затем определите функцию<code> reset ()</code>, которая возвращает приложение в исходное состояние, необходимое для повторного запуска игры после ее завершения. Добавьте в конец кода следующее:</p> + <p>Затем определите функцию<code> reset ()</code>, которая возвращает приложение в исходное состояние, необходимое для повторного запуска игры после её завершения. Добавьте в конец кода следующее:</p> <pre class="brush: js notranslate">function reset() { btn.style.display = 'block'; @@ -547,7 +547,7 @@ spinnerContainer.style.display = 'none';</pre> }</pre> </li> <li> - <p>Хорошо, хватит подготовки! Пришло время сделать игру доступной! Добавьте в свой код следующий блок. Функция <code>start ()</code> вызывает <code>draw ()</code>, чтобы запустить вращение спиннера и отобразить его в пользовательском интерфейсе, скрыть кнопку Start, чтобы вы не могли испортить игру, запустив ее несколько раз одновременно, и запускает вызов <code>setTimeout ()</code>, который выполняется функция <code>setEndgame ()</code> по прошествии случайного интервала от 5 до 10 секунд. Следующий блок также добавляет обработчик событий к вашей кнопке для запуска функции <code>start ()</code> при ее нажатии.</p> + <p>Хорошо, хватит подготовки! Пришло время сделать игру доступной! Добавьте в свой код следующий блок. Функция <code>start ()</code> вызывает <code>draw ()</code>, чтобы запустить вращение спиннера и отобразить его в пользовательском интерфейсе, скрыть кнопку Start, чтобы вы не могли испортить игру, запустив её несколько раз одновременно, и запускает вызов <code>setTimeout ()</code>, который выполняется функция <code>setEndgame ()</code> по прошествии случайного интервала от 5 до 10 секунд. Следующий блок также добавляет обработчик событий к вашей кнопке для запуска функции <code>start ()</code> при её нажатии.</p> <pre class="brush: js notranslate">btn.addEventListener('click', start); @@ -561,7 +561,7 @@ function start() { <div class="blockIndicator note"> <p><strong>Note</strong>: Вы увидите, что этот пример вызывает <code>setTimeout()</code> без сохранения возвращаемого значения. (не <code>let myTimeout = setTimeout(functionName, interval)</code>.) </p> - <p>Это прекрасно работает, если вам не нужно очищать интервал / тайм-аут в любой момент. Если вы это сделаете, вам нужно будет сохранить возвращенный идентификатор!</p> + <p>Это прекрасно работает, если вам не нужно очищать интервал / тайм-аут в любой момент. Если вы это сделаете, вам нужно будет сохранить возвращённый идентификатор!</p> </div> <p>Конечным результатом предыдущего кода является то, что при нажатии кнопки «Start» отображается спиннер, и игроки вынуждены ждать произвольное количество времени, прежде чем их попросят нажать их кнопку. Эта последняя часть обрабатывается функцией <code>setEndgame ()</code>, которую вы определите позже.</p> @@ -602,7 +602,7 @@ function start() { <li>Во-первых, отмените анимацию спиннера с помощью {{domxref("window.cancelAnimationFrame", "cancelAnimationFrame()")}} (всегда полезно очистить ненужные процессы), и скройте контейнер счетчика.</li> <li>Затем, отобразите абзац с результатами и установите для его текстового содержимого значение "PLAYERS GO!!" чтобы сообщить игрокам, что теперь они могут нажать свою кнопку, чтобы победить.</li> <li>Прикрепите к документу обработчик событий <code><a href="/en-US/docs/Web/API/Document/keydown_event">keydown</a></code> . При нажатии любой кнопки запускается функция <code>keyHandler()</code>.</li> - <li>Внутри <code>keyHandler()</code>, код включает объект события в качестве параметра (представленного <code>e</code>) — его свойство {{domxref("KeyboardEvent.key", "key")}} содержит только что нажатую клавишу, и вы можете использовать это для ответа на определенные нажатия клавиш определенными действиями.</li> + <li>Внутри <code>keyHandler()</code>, код включает объект события в качестве параметра (представленного <code>e</code>) — его свойство {{domxref("KeyboardEvent.key", "key")}} содержит только что нажатую клавишу, и вы можете использовать это для ответа на определённые нажатия клавиш определёнными действиями.</li> <li>Установите для переменной <code>isOver</code> значение false, чтобы мы могли отслеживать, были ли нажаты правильные клавиши, чтобы игрок 1 или 2 выиграл. Мы не хотим, чтобы игра заканчивалась при нажатии неправильной клавиши.</li> <li>Регистрация <code>e.key</code> в консоли, это полезный способ узнать значение различных клавиш, которые вы нажимаете.</li> <li>Когда <code>e.key</code> принимает значение "a", отобразить сообщение о том, что Player 1 выиграл, а когда <code>e.key</code> это "l", отобразить сообщение о том, что Player 2 выиграл. (<strong>Note:</strong> Это будет работать только со строчными буквами a и l — если переданы прописные A или L , это считается другими клавишами!) Если была нажата одна из этих клавиш, установите для <code>isOver</code> значение <code>true</code>.</li> @@ -619,7 +619,7 @@ function start() { <h2 id="Заключение">Заключение</h2> -<p>Вот и все — все основы асинхронных циклов и интервалов рассмотрены в статье. Вы найдете эти методы полезными во многих ситуациях, но постарайтесь не злоупотреблять ими! Поскольку они по-прежнему выполняются в основном потоке, тяжелые и интенсивные колбэки (особенно те, которые управляют DOM) могут действительно замедлить страницу, если вы не будете осторожны.</p> +<p>Вот и все — все основы асинхронных циклов и интервалов рассмотрены в статье. Вы найдёте эти методы полезными во многих ситуациях, но постарайтесь не злоупотреблять ими! Поскольку они по-прежнему выполняются в основном потоке, тяжёлые и интенсивные колбэки (особенно те, которые управляют DOM) могут действительно замедлить страницу, если вы не будете осторожны.</p> <p>{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Introducing", "Learn/JavaScript/Asynchronous/Promises", "Learn/JavaScript/Asynchronous")}}</p> @@ -628,7 +628,7 @@ function start() { <ul> <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Concepts">Основные понятия асинхронного программирования</a></li> <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Introducing">Введение в асинхронный JavaScript</a></li> - <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Timeouts_and_intervals">Объединенный асинхронный JavaScript: Таймауты и интервалы</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Timeouts_and_intervals">Объединённый асинхронный JavaScript: Таймауты и интервалы</a></li> <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Promises">Graceful asynchronous programming with Promises</a></li> <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Async_await">Сделайте асинхронное программирование легче с async и await</a></li> <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Choosing_the_right_approach">Choosing the right approach</a></li> |