async / await
Синтактическая надстройка над промисами. Зручний спосіб написання асинхронного коду, який ззовні схожий на синхронний. Цей механізм був доданий до стандарту ECMAScript 2017 (ES8) і став дуже популярним серед розробників завдяки його зручності та зрозумілості. Будь-яка функція може бути асинхронною.
async
Обява
async function asyncFn(){
//завжи повертає Промис
}
const asyncFn = async()=>{
//завжи повертає Промис
}
Для оголошення асинхронного методу об'єкта async додається перед іменем методу.
const user = {
async getUsername() {
// ...
},
};
}
Для оголошення асинхронного методу класу також використовується async перед іменем методу.
class User {
async getUsername() {
// ...
}
}
Виклик
Приклад 1 нормальне повернення
asyncFn() .then(value=>console.log(value))
Приклад 2 повернення помилки
const asyncFn = async()=>{
throw new Error ('It is error')
}
asyncFn()
.then(value=>console.log(value))
.catch(error=>console.log(error))
Приклад 3 Очикування результату промісу та виконання асінхронного виклику
const timerPromise =()=>
new Promise((resolve, reject)=>
setTimeout(()=>resolve(),2000))
const asyncFN=async()=>{
console.log('Timer start')
await timerPromise()
console.log('timer end')
}
asyncFN() //Віклик асинхронної функції
console.log('after async') //Будк виконано відразу після попередньої невважаючи що попередня ще не закіньчена
Приклад 4 Якщо не вказувати значення для повернення, буде створений проміс зі значенням undefined.
const foo = async () => {
// Не вказуємо значення для повернення
};
foo().then(value => {
console.log(value); // undefined
});
await
Всередині асинхронних функцій можна використовувати оператор await, розмістивши його праворуч від будь-якого виразу, який повертає проміс. Коли інтерпретатор зустрічає await, він призупиняє виконання функції і чекає, доки не завершиться виконання промісу, який знаходиться праворуч від await.
const foo = async () => {
console.log("Before await");
const promiseValue = await new Promise(resolve => {
setTimeout(() => resolve(5), 2000)
});
console.log("After await", promiseValue);
};
foo(); // через 2 секунди виведеться в консоль "After await" 5
Вже .then не потрібна і повернеться саме значення результат функції а не проміс
HTTP-запити
Використаємо синтаксис async/await при роботі з HTTP-запитами, щоб зробити код більш читабельним.
const fetchUsers = async () => {
const response = await axios.get("<https://jsonplaceholder.typicode.com/users>");
return response.data;
};
fetchUsers()
.then(users => console.log(users));
Обробка помилок
Якщо результат асинхронної функції (проміс) не використовується в зовнішньому коді, помилки оброблюються у самому тілі функції за допомогою конструкції try…catch. Значення параметра error у блоці catch — це помилка, яку генерує await, якщо проміс був відхилений.
const fetchUsers = async () => {
try {
const response = await axios.get("<https://jsonplaceholder.typicode.com/users>");
console.log(response.data);
} catch(error) {
console.log(error);
}
};
Приклади
Виконання декількох запитів HTTP асінхронно
async function f1(){
const url = 'http://lovalhost:3000/book';
//сам запит до сервера робимо аасинхронно для швидкості
const p1 = fetch(url);
const p2 = fetch(url);
const p3 = fetch(url);
const p4 = fetch(url);
const p5 = fetch(url);
//кладемо проміси у масив
const promise = [p1,p2,p3,p4,p5]
//а тепер у результат кладемо результати проміі і чекаємо тільки коли усі вони виконаються
const result = await Promise.allSettled(promise);
console.log(result)
}
//Викликаємо саму функцію
f1();