Работа с асинхронностью стала намного проще благодаря шаблону async/await. Это делает асинхронные задачи почти такими же простыми, как и обычные синхронные операции:

async function asyncCheckPokemon() {
  const response = await fetch("https://pokeapi.co/api/v2/pokemon/25");
  const pikachuJSON = await response.json();
  // Prints "Look mum, no callbacks! Pokémon #25 is pikachu"
  console.log(
    `Look mum, no callbacks! ` +
    `Pokémon #${pikachuJSON.id} is ${pikachuJSON.name}`
  );
}
asyncCheckPokemon();

Тем не менее, все еще есть некоторые подводные камни, которые следует учитывать при работе с этим шаблоном. Функция в предыдущем примере ничего не возвращает, но выводит в консоль некоторый текст.

Теперь давайте внесем небольшое изменение, чтобы функция возвращала строку, а не печатала ее:

async function asyncCheckPokemon() {
  const response = await fetch("https://pokeapi.co/api/v2/pokemon/25");
  const pikachuJSON = await response.json();
  return (
    `Look mum, no callbacks! ` +
    `Pokémon #${pikachuJSON.id} is ${pikachuJSON.name}`
  );
}
const pikachuMessage = asyncCheckPokemon();

Каково значение переменной pikachuMessage? Если бы вы сказали, что это строка «Смотри, мама, никаких обратных вызовов!» Покемон № 25 — это пикачу, это неправильно. Переменная — это обещание, которое разрешается в эту строку. Но почему?

Шаблон async/await работает следующим образом: когда вы выполняете асинхронную задачу с использованием ключевого слова await, функция, содержащая вызов, должна быть "приостановлена" до завершения асинхронной задачи.

Дело в том, что вы не можете полностью заблокировать выполнение своего скрипта, потому что это также заблокирует цикл обработки событий, задача больше не будет асинхронной.

Эта проблема решается с помощью промисов. Если функция, содержащая асинхронную задачу, возвращает обещание, асинхронная операция заблокирует только эту функцию.

Теперь, как вы обрабатываете async функции, которые возвращают значения? Его следует вызывать из другой функции async, а для выполнения вызова следует использовать await. Это должно выглядеть так:

async function asyncCheckPokemon() {
  const response = await fetch("https://pokeapi.co/api/v2/pokemon/25");
  const pikachuJSON = await response.json();
  return (
    `Look mum, no callbacks! ` +
    `Pokémon #${pikachuJSON.id} is ${pikachuJSON.name}`
  );
}
async function printPikachuMessage() {
    const pikachuMessage = await asyncCheckPokemon();
    // Prints "Look mum, no callbacks! Pokémon #25 is pikachu"
    console.log(pikachuMessage);
}
printPikachuMessage();

Но что, если вы хотите вызвать получение значения из функции async на верхнем уровне (то есть не внутри функции)? В Node.js и Chrome это возможно, если скрипт представляет собой модуль ES6. В Node.js убедитесь, что файл имеет расширение «.mjs», а для Chrome добавьте атрибут type="module" к тегу <script>.

Но если вы не можете использовать модули, вам придется использовать функцию async, которая ничего не возвращает, а затем вызывать эту функцию на верхнем уровне. Для этого вы можете использовать немедленно вызываемое функциональное выражение (IIFE).

Станьте лучшим разработчиком JavaScript! Простые, действенные шаги для повышения уровня ваших навыков JavaScript, прямо в вашей почте. Нажмите здесь, чтобы подписаться: https://nicozerpa.com/newsletter/