В Интернете многие вещи, как правило, имеют много времени – если вы запрашиваете 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:
__________ 🐣 Обо мне __________
- Я основатель Девчалленг
- Подписаться на мой YouTube канал
- Следуй за мной на Твиттер
- Присоединяйтесь к Раздор
Оригинал: “https://www.freecodecamp.org/news/learn-promise-async-await-in-20-minutes/”