Изследване на вътрешната работа на setTimeout(), Promises и Async/Await за ефективно асинхронно програмиране в JavaScript

Разбиране на значението на Asynchronous JS

АсинхроненJavaScript ни позволява да изпълняваме множество задачи едновременно, без да чакаме всяка задача да бъде завършена, преди да преминем към следващата. Нека си го визуализираме с пример, представете си фабрика, която произвежда различни продукти с множество поточни линии. При синхронното програмиране работниците изпълняват една поръчка, преди да преминат към следващата, което води до дълго време за чакане за клиентите. При асинхронното програмиране работниците могат да работят по множество поръчки едновременно, което води до по-бързо изпълнение на поръчките.

В асинхронния JavaScript, монтажните линии представляват асинхронни функции, а поръчките представляват задачи. Когато дадена задача е присвоена на поточна линия, тя се добавя към опашка, за да се изпълни асинхронно. Работниците на поточната линия започват да работят по задачите в опашката, но не изчакват задачата да бъде завършена, преди да преминат към следващата. Това означава, че когато дадена задача включва отнемаща време операция, като напримерAPI*повикване, работникът на поточната линия не чака извикването на API* да завърши, преди да премине към следващата задача.

Каква е разликата с асинхронния JS?

Асинхронният JavaScript е от решаващо значение за уеб разработчиците и големите софтуерни компании по множество причини.

  • Той подобрява производителността на уебсайта ви, позволявайки досадни операции да се изпълняват във фонов режим
  • Вашият уебсайт вече може да обработва множество заявки
  • Ще можете да организирате кода си добре

Какво ни казват изследванията за тенденциите?

Според Google Insights средното време за зареждане на мобилен уебсайт е около 22 секунди, докато средното време за зареждане на уебсайт за настолен компютър е около 15 секунди.

Проучванията обаче показват, че потребителите са готови да изчакат само до 3 секунди за зареждане на уебсайт, преди да започнат да го изоставят.

Така че виждате колко важно е да изобразите уеб страницата възможно най-бързо, за да увеличите привличането на клиенти.

Да преминем към забавната част: CODDEEEEE!

Визуализиране на setTimeout()

Нека да разгледаме този код:

Следните кодови регистрационни файлове:

Така че знаем, че JS работи ред по ред отгоре надолу и очакваме, че „1st“ трябва да бъде регистрирано в началото. Но в крайна сметка това не се случи и вместо това най-накрая се регистрира.

Нека да проучим какво се случва:

Първият ни ред от код с 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 или зареждане на големи файлове, без да блокират основната нишка.

Визуализиране на async/await

Това е нова концепция, която беше много необходима в 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 и promises, можем да изпълняваме множество задачи едновременно, без да чакаме всяка задача да завърши. Това може значително да подобри производителността на нашите приложения и да осигури по-добро потребителско изживяване. Със солидно разбиране на асинхронното програмиране можем да пишем по-ефективни и мащабируеми приложения.

console.log("Coding for Life 🍻")