Изучение внутренней работы setTimeout(), Promises и Async/Await для эффективного асинхронного программирования в JavaScript
Понимание смысла асинхронного JS
АсинхронныйJavaScript позволяет нам выполнять несколько задач одновременно, не дожидаясь завершения каждой задачи, прежде чем переходить к следующей. Давайте представим это на примере, представьте себе фабрику, которая производит разные продукты с несколькими сборочными линиями. При синхронном программировании рабочие выполняют один заказ, прежде чем перейти к следующему, что приводит к длительному времени ожидания клиентов. В асинхронном программировании рабочие могут работать над несколькими заказами одновременно, что приводит к более быстрому выполнению заказов.
В асинхронном JavaScript сборочные линии представляют асинхронные функции, а заказы — задачи. Когда задача назначается сборочной линии, она добавляется в очередь для асинхронного выполнения. Рабочие сборочной линии начинают работать над задачами в очереди, но они не ждут завершения задачи, прежде чем перейти к следующей. Это означает, что когда задача включает в себя трудоемкую операцию, такую как вызов API*, работник сборочной линии не ждет завершения вызова API*, прежде чем перейти к следующей задаче.
Какая разница, что делает асинхронный JS?
Асинхронный JavaScript имеет решающее значение для веб-разработчиков и крупных компаний-разработчиков программного обеспечения по нескольким причинам.
- Это повышает производительность вашего веб-сайта, позволяя выполнять утомительные операции в фоновом режиме.
- Теперь ваш сайт может обрабатывать несколько запросов
- Вы сможете хорошо организовать свой код
Что исследования говорят нам о тенденциях?
По данным Google Insights, среднее время загрузки веб-сайта для мобильных устройств составляет около 22 секунд, а среднее время загрузки веб-сайта для настольных компьютеров — около 15 секунд.
Однако исследования показали, что пользователи готовы ждать загрузки веб-сайта всего до 3 секунд, прежде чем они начнут его покидать.
Итак, вы видите, насколько важно отображать веб-страницу как можно быстрее, чтобы увеличить привлечение клиентов.
Давайте перейдем к самой веселой части: CODDEEEEE!
Визуализация setTimeout()
Давайте посмотрим на этот код:
Журналы следующего кода:
Итак, мы знаем, что JS выполняется построчно сверху вниз, и ожидаем, что «1-й» должен быть зарегистрирован в начале. Но в конце концов этого не произошло, и вместо этого, наконец, вошли в систему.
Давайте посмотрим, что происходит:
Наша первая строка кода с setTimeout() удерживает строку «1st» от ведения журнала консоли в течение 1000 миллисекунд, что дает достаточно времени для следующих 3 строк, чтобы зарегистрировать свои значения. Теперь вы можете подумать, зачем вообще кому-то нужна такая встроенная функция?
Представьте себе веб-сайт, который требует отображать некоторые предложения для клиентов, если они проводят определенное время на своем веб-сайте для создания клиентской базы. Как мы могли это сделать? Что ж, давайте посмотрим на некоторый исходный код для этого:
function showPopup(delay, callback) { setTimeout(callback, delay); } // Set the amount of time to wait before showing the popup (in milliseconds) const popupDelay = 30000; // 30 seconds // Define the callback function to show the offer popup function showOfferPopup() { // Get a reference to the popup element const modal = document.getElementById('offer-popup'); // Show the popup modal.style.display = 'block'; } // Call the showModalPopup function with the delay and callback function showPopup(popupDelay, showOfferPopup);
У нас есть функция showPopup(), которая принимает обратный вызов и задержку в качестве аргументов, а функция showOfferPopup() добавляет всплывающее окно в DOM, когда setTimeout() срабатывает после 30 секунд прокрутки сайта пользователем.
Визуализация обещаний
Согласно MDN, Promise — это встроенный объект JavaScript, который представляет возможное завершение (или сбой) асинхронной операции и ее результирующее значение. Промисы предоставляют способ обработки асинхронных операций более структурированным и интуитивно понятным способом. На этот раз давайте воспользуемся концепцией Promise в нашем коде:
const url = 'https://jsonplaceholder.typicode.com/posts' function fetchData(url) { return new Promise((resolve, reject) => { fetch(url) .then(response => { if (!response.ok) { throw new Error(`HTTP error! Status: ${response.status}`); } return response.json(); }) .then(data => { resolve(data); }) .catch(error => { reject(error); }); }); } fetchData(url) .then(data => { console.log(data); }) .catch(error => { console.error(error); });
Предположим, мы пытаемся написать GET-запрос и получить данные, содержащие изображения. В этом коде наш fetchData() вернет обещание, которое, в свою очередь, вернет нам ответ, который будет выполняться им в фоновом режиме, не мешая текущему времени загрузки веб-сайта.
Этот вызов API предоставляет нам 100 идентификаторов, но в реальной жизни вызов API будет состоять из 1000 идентификаторов, которые, если их не обрабатывать асинхронно, остановят рендеринг всего веб-сайта и значительно увеличат время загрузки.
Даже если ответ будет неудачным, он вернет нам ошибку, соответствующую сбою. Мы возвращаем наши данные в формате JSON, и наш .then() записывает данные в нашу консоль.
В конечном счете, JavaScript является однопоточным, поэтому он не может выполнять несколько задач одновременно. Асинхронные операции с использованием Promise позволяют разработчикам выполнять трудоемкие задачи, такие как выборка данных из API или загрузка больших файлов, не блокируя основной поток.
Визуализация асинхронного/ожидания
Это новая концепция, которая была очень нужна в JS. Это синтаксис для обработки асинхронного кода в JavaScript. Ключевое слово async
используется для пометки функции как асинхронной, а ключевое слово await
используется для приостановки выполнения функции до тех пор, пока промис не будет разрешен.
Давайте посмотрим пример:
async function getData() { try { const response = await fetch('https://api.example.com/data'); const data = await response.json(); return data; } catch (error) { console.error(error); } } getData().then(data => { console.log(data); });
В этом примере мы определили асинхронную функцию getData(), которая извлекает некоторые данные из API с помощью метода fetch(). Затем мы используем ключевое слово await для ожидания ответа от API перед преобразованием его в JSON с помощью метода response.json(). Наконец, мы возвращаем проанализированные данные из функции getData().
Мы используем блок try/catch для обработки любых ошибок, которые могут возникнуть во время работы методов fetch() и .json(). Если возникает ошибка, мы записываем ее в консоль.
Чтобы вызвать функцию getData(), мы используем метод then() для обработки возвращаемых данных. Выводим данные в консоль.
Использование async/await делает асинхронный код более читабельным и понятным. Это позволяет разработчикам писать асинхронный код, похожий на синхронный код, что может помочь снизить когнитивную нагрузку и упростить обслуживание кода.
Заключение!
В заключение, асинхронный JavaScript — это мощный инструмент, который позволяет нам писать эффективный и отзывчивый код. Используя такие функции, как async/await, setTimeout и обещания, мы можем выполнять несколько задач одновременно, не дожидаясь завершения каждой задачи. Это может значительно повысить производительность наших приложений и улучшить взаимодействие с пользователем. Обладая глубоким пониманием асинхронного программирования, мы можем писать более эффективные и масштабируемые приложения.
console.log("Coding for Life 🍻")