Рубрики
Без рубрики

Как изучать JavaScript обещания и Async / ждут за 20 минут

В Интернете многие вещи, как правило, имеют много времени – если вы запрашиваете API, это может занять некоторое время, чтобы получить ответ. Следовательно, асинхронное программирование является важным навыком для разработчиков. При работе с асинхронными операциями в JavaScript мы часто слышим термин обещание. Но это может быть сложно

В Интернете многие вещи, как правило, имеют много времени – если вы запрашиваете API, это может занять некоторое время, чтобы получить ответ. Следовательно, асинхронное программирование является важным навыком для разработчиков.

При работе с асинхронными операциями в JavaScript мы часто слышим термин Обещание Отказ Но может быть сложно понять, как они работают и как их использовать.

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

  • Задача 1: Обещание Основы объяснены, используя мой день рождения
  • Задача 2: построить угадать игру
  • Задача 3: Получить информацию о стране от API
  • Задача 4: извлечь соседние страны страны

Если вы хотите следовать, обязательно скачайте здесь ресурсы: https://bit.ly/3m4bjwi.

Задача 1: Обещание Основы объяснены, используя мой день рождения

Мой друг Кайо обещает сделать торт на мой день рождения через две недели.

Если все идет хорошо, и Kayo не болеет, у нас будет определенное количество тортов. (Торты считаются счетными в этом руководстве 😆). В противном случае, если кайо заболеет, у нас нет тортов.

В любом случае, мы все еще будем иметь вечеринку.

Для этой первой задачи мы переведем эту историю в код. Во-первых, давайте создадим функцию, которая возвращает Обещание :

const onMyBirthday = (isKayoSick) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (!isKayoSick) {
        resolve(2);
      } else {
        reject(new Error("I am sad"));
      }
    }, 2000);
  });
};

В JavaScript мы можем создать новый Обещание с Новое обещание () , который принимает функцию в качестве аргумента: (разрешать, отклонить) = > {} .

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

Давайте посмотрим на код выше.

Когда мы запускаем OnMyBirtyday Функция, после 2000 мс :

  • Если кайо не болен, то мы бежим решить с 2 Как аргумент
  • Если кайо болен, то мы бежим Отклонить с Новая ошибка («Мне грустно») как аргумент. Даже если вы можете пройти что-нибудь до Отклонить В качестве аргумента рекомендуется пройти через Ошибка объект.

Теперь, потому что OnMybirthday () Возвращает Обещание У нас есть доступ к тогда , поймать и Наконец методы.

И у нас также есть доступ к аргументам, которые были переданы в решить и Отклонить раньше в … тогда и поймать Отказ

Давайте посмотрим на код.

Если кайо не болен:

onMyBirthday(false)
  .then((result) => {
    console.log(`I have ${result} cakes`); // In the console: I have 2 cakes  
  })
  .catch((error) => {
    console.log(error); // Does not run
  })
  .finally(() => {
    console.log("Party"); // Shows in the console no matter what: Party
  });

Если кайо болен:

onMyBirthday(true)
  .then((result) => {
    console.log(`I have ${result} cakes`); // does not run 
  })
  .catch((error) => {
    console.log(error); // in console: Error: I am sad
  })
  .finally(() => {
    console.log("Party"); // Shows in the console no matter what: Party
  });

Хорошо, так к настоящему времени, я надеюсь, что вы получите основную идею Обещание Отказ Давайте переместимся на задачу 2.

Задача 2: построить угадать игру

Требования:

  • История пользователя: пользователь может ввести номер
  • История пользователя: система выбирает случайное число от 1 до 6
  • История пользователя: если номер пользователя равен случайным номером, дайте пользователю 2 балла
  • История пользователя: если номер пользователя отличается от случайный номер на 1, Дайте пользователю 1 балл. В противном случае дайте пользователю 0 баллов
  • История пользователя: пользователь может играть в игру, пока они хотят к

Для первых 4 пользовательских историй, давайте создадим Энтиролик Функция и вернуть Обещание :

const enterNumber = () => {
  return new Promise((resolve, reject) => {
    // Let's start from here
  });
};

Первое, что нам нужно сделать, это попросить номер от пользователя и выбирать случайное число от 1 до 6:

const enterNumber = () => {
  return new Promise((resolve, reject) => {
    const userNumber = Number(window.prompt("Enter a number (1 - 6):")); // Ask the user to enter a number
    const randomNumber = Math.floor(Math.random() * 6 + 1); // Pick a random number between 1 and 6
  });
};

Теперь Учетное число Может ввести значение, это не число. Если это так, давайте назовем Отклонить Функция с ошибкой:

const enterNumber = () => {
  return new Promise((resolve, reject) => {
    const userNumber = Number(window.prompt("Enter a number (1 - 6):")); // Ask user to enter a number
    const randomNumber = Math.floor(Math.random() * 6 + 1); // Pick a random number between 1 and 6

    if (isNaN(userNumber)) {
      reject(new Error("Wrong Input Type")); // If the user enters a value that is not a number, run reject with an error
    }
  });
};

Следующее, что мы хотим сделать, это проверить Если Учетное число равно случайное число Если так, мы хотим дать пользователю 2 балла, и мы можем запустить решить Функция, проходящая объект {очки: 2, RandomNumber} Отказ Уведомление здесь, что мы также хотим знать Случайное число Когда обещание решено

Если Учетное число отличается от Случайное число К одному, тогда мы даем пользователю 1 балл. В противном случае мы даем пользователю 0 баллов:

return new Promise((resolve, reject) => {
  const userNumber = Number(window.prompt("Enter a number (1 - 6):")); // Ask the user to enter a number
  const randomNumber = Math.floor(Math.random() * 6 + 1); // Pick a random number between 1 and 6

  if (isNaN(userNumber)) {
    reject(new Error("Wrong Input Type")); // If the user enters a value that is not a number, run reject with an error
  }

  if (userNumber === randomNumber) {
    // If the user's number matches the random number, return 2 points
    resolve({
      points: 2,
      randomNumber,
    });
  } else if (
    userNumber === randomNumber - 1 ||
    userNumber === randomNumber + 1
  ) {
    // If the user's number is different than the random number by 1, return 1 point
    resolve({
      points: 1,
      randomNumber,
    });
  } else {
    // Else return 0 points
    resolve({
      points: 0,
      randomNumber,
    });
  }
});

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

const continueGame = () => {
  return new Promise((resolve) => {
    if (window.confirm("Do you want to continue?")) { // Ask if the user want to continue the game with a confirm modal
      resolve(true);
    } else {
      resolve(false);
    }
  });
};

Уведомление здесь, что мы создаем Обещание С Но это не использует Отклонить Перезвоните. Это совершенно нормально.

Теперь давайте создадим функцию для обработки догадки:

const handleGuess = () => {
  enterNumber() // This returns a Promise
    .then((result) => {
      alert(`Dice: ${result.randomNumber}: you got ${result.points} points`); // When resolve is run, we get the points and the random number 
      
      // Let's ask the user if they want to continue the game
      continueGame().then((result) => {
        if (result) {
          handleGuess(); // If yes, we run handleGuess again
        } else {
          alert("Game ends"); // If no, we show an alert
        }
      });
    })
    .catch((error) => alert(error));
};

handleGuess(); // Run handleGuess function

Вот когда мы называем поручитель , Enternumber () Теперь возвращает Обещание :

  • Если Обещание решается, мы называем тогда Способ и показать сообщение о предупреждении. Мы также спрашиваем, хочет ли пользователь продолжить.
  • Если Обещание Отклоняется, мы покажем сообщение о предупреждении с ошибкой.

Как видите, код довольно сложно прочитать.

Давайте рефоктором Хранитель функционировать немного, используя Async/await синтаксис:

const handleGuess = async () => {
  try {
    const result = await enterNumber(); // Instead of the then method, we can get the result directly by just putting await before the promise

    alert(`Dice: ${result.randomNumber}: you got ${result.points} points`);

    const isContinuing = await continueGame();

    if (isContinuing) {
      handleGuess();
    } else {
      alert("Game ends");
    }
  } catch (error) { // Instead of catch method, we can use the try, catch syntax
    alert(error);
  }
};

Вы можете увидеть, что мы создали async Функция, положив async перед кронштейнами. потом в async Функция:

  • Вместо тогда Метод, мы можем получить результаты непосредственно просто поставив Ждите до обещания
  • Вместо поймать Метод, мы можем использовать попробуй, поймать синтаксис

Вот весь код для этой задачи снова для вашей справки:

const enterNumber = () => {
  return new Promise((resolve, reject) => {
    const userNumber = Number(window.prompt("Enter a number (1 - 6):")); // Ask the user to enter a number
    const randomNumber = Math.floor(Math.random() * 6 + 1); // Pick a random number between 1 and 6

    if (isNaN(userNumber)) {
      reject(new Error("Wrong Input Type")); // If the user enters a value that is not a number, run reject with an error
    }

    if (userNumber === randomNumber) { // If the user's number matches the random number, return 2 points
      resolve({
        points: 2,
        randomNumber,
      });
    } else if (
      userNumber === randomNumber - 1 ||
      userNumber === randomNumber + 1
    ) { // If the user's number is different than the random number by 1, return 1 point
      resolve({
        points: 1,
        randomNumber,
      });
    } else { // Else return 0 points
      resolve({
        points: 0,
        randomNumber,
      });
    }
  });
};

const continueGame = () => {
  return new Promise((resolve) => {
    if (window.confirm("Do you want to continue?")) { // Ask if the user want to continue the game with a confirm modal
      resolve(true);
    } else {
      resolve(false);
    }
  });
};

const handleGuess = async () => {
  try {
    const result = await enterNumber(); // Instead of the then method, we can get the result directly by just putting await before the promise

    alert(`Dice: ${result.randomNumber}: you got ${result.points} points`);

    const isContinuing = await continueGame();

    if (isContinuing) {
      handleGuess();
    } else {
      alert("Game ends");
    }
  } catch (error) { // Instead of catch method, we can use the try, catch syntax
    alert(error);
  }
};

handleGuess(); // Run handleGuess function

Хорошо, мы сделаем со вторым заданием. Давайте перейдем к третьему.

Задача 3: Получить информацию о стране от API

Вы увидите Обещания Используется много при получении данных из API.

Если вы откроете https://restcountries.eu/rest/v2/Alpha/Col В новом браузере вы увидите данные страны в формате JSON. Используя Fetch API мы можем получить данные:

const fetchData = async () => {
  const res = await fetch("https://restcountries.eu/rest/v2/alpha/col"); // fetch() returns a promise, so we need to wait for it

  const country = await res.json(); // res is now only an HTTP response, so we need to call res.json()

  console.log(country); // Columbia's data will be logged to the dev console
};

fetchData();

Теперь, когда у нас есть данные о странах, которые мы хотим, давайте перейдем к последней задаче.

Задача 4: извлечь соседние страны страны

Если вы открываете задачу 4, вы увидите, что у нас есть fetchcountry. Функция, которая извлекает данные с конечной точки: https://restcountries.eu/rest/v2/Alpha/$@alalpha3Code} где Alpha3Code это код страны. Вы также видите, что он поймает ?| Ошибка . Это может произойти при получении данных.

// Task 4: get the neigher countries of Columbia

const fetchCountry = async (alpha3Code) => {
  try {
    const res = await fetch(
      `https://restcountries.eu/rest/v2/alpha/${alpha3Code}`
    );

    const data = await res.json();

    return data;
  } catch (error) {
    console.log(error);
  }
};

Давайте создадим fetchcountryandneighbors Функция и извлечь информацию Колумбии, проходя Col Как Alpha3Code Отказ

const fetchCountryAndNeighbors = async () => {
  const columbia = await fetchCountry("col");

  console.log(columbia);
};

fetchCountryAndNeighbors();

Теперь, если вы посмотрите в свою консоль, вы можете увидеть, как объект выглядит так:

В объекте есть граница Свойство, которое является списком Alpha3Codes Для соседних стран Колумбии.

Теперь, если мы попытаемся получить соседние страны:

  const neighbors = 
    columbia.borders.map((border) => fetchCountry(border));

Тогда, Соседи будет массив Обещание объекты.

При работе с массивом обещаний нам нужно использовать Обещание. Все :

const fetchCountryAndNeigbors = async () => {
  const columbia = await fetchCountry("col");

  const neighbors = await Promise.all(
    columbia.borders.map((border) => fetchCountry(border))
  );

  console.log(neighbors);
};

fetchCountryAndNeigbors();

В Консоль Мы должны быть в состоянии увидеть список объектов страны.

Вот весь код для задания снова для вашей справки:

const fetchCountry = async (alpha3Code) => {
  try {
    const res = await fetch(
      `https://restcountries.eu/rest/v2/alpha/${alpha3Code}`
    );

    const data = await res.json();

    return data;
  } catch (error) {
    console.log(error);
  }
};

const fetchCountryAndNeigbors = async () => {
  const columbia = await fetchCountry("col");

  const neighbors = await Promise.all(
    columbia.borders.map((border) => fetchCountry(border))
  );

  console.log(neighbors);
};

fetchCountryAndNeigbors();

Заключение

После завершения этих 4 задач вы можете увидеть, что Обещание полезно, когда дело доходит до асинхронных действий или вещей, которые не происходят одновременно.

Вы можете увидеть это на практике в одном из моих учебных пособий, где мы создаем приложение с нуля с помощью React и Next.js:

__________ 🐣 Обо мне __________

Оригинал: “https://www.freecodecamp.org/news/learn-promise-async-await-in-20-minutes/”