Приветствую вас дорогие читатели. Сегодня мы познакомимся с основами асинхронного программирования в javascript, а именно научимся создавать асинхронные функции. Поехали!
Для начала напишем обычную функцию.
function fun() {
return "answer";
}
console.log(fun());
Она возвращает в консоль некое строковое значение 'answer'. Теперь сделаем ее асинхронной.
async function fun() {
return "answer";
}
console.log(fun());
Для этого просто нужно добавить приставку 'async'. Обратите внимание что теперь функция возвращает не строку, а объект Promise. Promise это специальный объект предоставляющий удобный способ организации асинхронного кода. Чтобы извлечь наше строковое значение 'answer' из асинхронной функции необходимо записать так.
async function fun() {
return "answer";
}
fun().then(function(result){
console.log(result);
});
C помощью метода then() мы может обрабатывать объект promise. Данный метод может принимать две функции:
then(fulfilled, rejected)
fulfilled - вызывается при успешном выполнении функции
rejected - вызывается при ошибке выполнения в функции
В нашем примере в качестве анонимной функции мы обрабатываем успешный ответ и возвращает его в виде строки 'answer'.
Рассмотрим пример с ошибкой:
async function fun() {
return per;
}
fun().then(function(result){
console.log(result);
}, function(){
console.log('Произошла ошибка при выполнении кода в функции');
});
Здесь мы попытались вернуть несуществующую переменную 'per' и в результате вместо успешного ответа получили сообщение об ошибке, благодаря отработки функции rejected.
Идем дальше! Рассмотрим пример работы асинхронных функций с методом fetch, который позволяет отправлять ajax запросы.
async function fun() {
var result = "Ответ не определен";
fetch(window.location.href).then(function(responce){
return responce.text();
}).then(function(res){
result = res;
}).catch(function(err){
result = "Соединение с интернетом разорвано!";
});
return result;
}
fun().then(function(answer){
console.log(answer);
});
В данном примере мы пытаемся получить html код текущей страницы с помощью get запроса и вернуть его в качестве ответа функции. Но вместо этого получаем "Ответ не определен", так как значение result возвращается не дожидаясь ответа от метода fetch(). Чтобы эту ситуацию исправить, достаточно к методу fecth() добавить ожидание с помощью ключевого слова 'await'.
async function fun() {
var result = "Ответ не определен";
await fetch(window.location.href).then(function(responce){
return responce.text();
}).then(function(res){
result = res;
}).catch(function(err){
result = "Соединение с интернетом разорвано!";
});
return result;
}
fun().then(function(answer){
console.log(answer);
});
Данный код уже вернет нужный результат в виде html-кода текущей страницы. С помощью приставки await можно поставить ожидание возврата ответа. То есть пока ответ не будет возвращен последующий код выполняться не будет. Ожидание await можно применять только в асинхронных функциях!
async function fun() {
var result = "Ответ не определен";
try{
var responce = await fetch(window.location.href);
result = await responce.text();
}catch(err){
return "Ошибка";
}
return result;
}
fun().then(function(answer){
console.log(answer);
});
Как видите благодаря await можно писать fetch запросы более удобно и понятно. Исключение try-catch необходимо для отлова возможных ошибок.
async function fun() {
var result = "Ответ не определен";
try{
var responce = await fetch(window.location.href);
result = await responce.json();
}catch(err){
return "Ошибка: " + err;
}
return result;
}
fun().then(function(answer){
console.log('answer',answer);
});
К примеру здесь мы намерено допустили ошибку, обработав запрос функцией json(). Обратите внимание что сама ошибка вывелась в ответе, что само по себе может быть не очень удобно. Для отлова ошибок у объекта promise существует метод catch() и чтобы им воспользоваться можно написать так.
async function fun() {
var result = "Ответ не определен";
try{
var responce = await fetch(window.location.href);
result = await responce.json();
}catch(err){
throw new Error("Ошибка:" + err);
}
return result;
}
fun().then(function(answer){
console.log('answer',answer);
}).catch(function(err){
console.log(err);
});
Ошибка отловленная в исключении теперь выводится в блоке catch у объекта promise.
throw new Error("Информация об исключении"); - инициализирует исключение у promise.
var par = 0;
async function fun() {
if(par !== 0){
return par;
}else{
throw new Error("Переменная равна нулю");
}
}
fun().then(function(answer){
console.log('answer',answer);
}).catch(function(err){
console.log(err);
}).finally(function(){
console.log('Ответ вернулся');
});
Блок finally() выполняется при любом исходе после получения ответа или отработке кода в promise.
Можно так же выставлять задержки в циклах.
const timeoutPromise = (timeout) => new Promise((resolve) => setTimeout(resolve, timeout));
async function countdown(){
for(var i = 10; i > 0; i--){
await timeoutPromise(1000);
console.log(i);
}
}
countdown();
Здесь мы написали обратный отсчет с задержкой в 1 секунду через цикл for, используя при этом promise timeoutPromise. Вообще промисы требуют отдельной темы для рассмотрения поэтому мы на этом остановимся.
Сегодня мы узнали как создаются асинхронные функции и как с ними работать, также разобрали примеры использования с методом fetch(). Надеюсь статья была для вас полезна. Подписывайтесь в группу Вконтакте и переходите на канал Youtube.
На этом у меня все, спасибо за внимание!