====== ПРОМИСИ ======
Виконання відкладених задач. Асінхронно.
===== Состояния промиса =====
* ожидание (panding)
* исполнен (resolve)
* отклонен (reject)
===== обявление промиса (Promise) =====
При створенні промісу всередині буде відразу вконана та дія. Сюди загоняємо те що повинно буде виконано у промісі.
const myPromise = new Promise ((resolve, reject)=>{
//Віполнение асинхронного действия нужно в результате візвать одну из функций resolve или reject
})
===== Обробка резуьтата промиса (.then) =====
В методах then прописуємо що буде виконано коли настане подія вдалого,невдалого або просто факта виконання проміса
promise.then(onFullFild).catch(onReject);
myPromse
.then(value => {
//действие в случае успешного віполнения
})
.catch (error=>{
//дія у випадку помилки
})
* Приклад 1
const isSuccess = true;
// Create promise
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
if (isSuccess) {
resolve("Success! Value passed to resolve function");
} else {
reject("Error! Error passed to reject function");
}
}, 2000);
});
// Registering promise callbacks
promise.then(
value => {
console.log(value); // "Success! Value passed to resolve function"
},
error => {
console.log(error); // "Error! Error passed to reject function"
}
);
У змінну promise буде записаний проміс (об'єкт) у стані pending, а через дві секунди, щойно буде викликаний resolve() або reject(), проміс перейде у стан fulfilled або rejected, і ми зможемо його обробити. Якщо функції onResolve і onReject містять складну логіку, їх для зручності оголошують як зовнішні функції і передають у метод then() за ім'ям.
===== Обробка помилки catch() =====
На практиці в методі then() обробляють тільки успішне виконання промісу.
Помилку його виконання обробляють у спеціальному методі **catch()** для «відловлювання» помилок.
const isSuccess = true;
// Create promise
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
if (isSuccess) {
resolve("Success! Value passed to resolve function");
} else {
reject("Error! Error passed to reject function");
}
}, 2000);
});
// Registering promise callbacks
promise
.then(value => {
console.log(value); // "Success! Value passed to resolve function"
})
.catch(error => {
console.log(error); // "Error! Error passed to reject function"
});
===== Метод finally() =====
метод може бути корисним, якщо необхідно виконати код після того, як проміс буде виконаний незалежно від результату (fulfilled або rejected).
Колбек-функція не отримає жодних аргументів, оскільки неможливо визначити, чи був проміс виконаний або відхилений. Тут буде виконуватися код, який необхідно запустити в будь-якому разі.
promise
.then(value => {
// Promise fulfilled
})
.catch(error => {
// Promise rejected
})
.finally(() => {
// Promise fulfilled or rejected
});
const isSuccess = true;
// Create promise
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
if (isSuccess) {
resolve("Success! Value passed to resolve function");
} else {
reject("Error! Error passed to reject function");
}
}, 2000);
});
// Registering promise callbacks
promise
.then(value => console.log(value)) // "Success! Value passed to resolve function"
.catch(error => console.log(error)) // "Error! Error passed to reject function"
.finally(() => console.log("Promise settled")); // "Promise settled"
===== Ланцюжки промісів then() =====
Метод then() повертає новий проміс, який у свою чергу отримує значення від своєї callback-функції onResolve. Ця особливість дозволяє формувати послідовність асинхронних операцій, зв'язуючи проміси в ланцюжок.
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(5);
}, 2000);
});
promise
.then(value => {
console.log(value); // 5
return value * 2;
})
.then(value => {
console.log(value); // 10
return value * 3;
})
.then(value => {
console.log(value); // 30
})
.catch(error => {
console.log(error);
})
.finally(() => {
console.log("finally");
});
===== Promise.resolve() і Promise.reject() =====
статичні методи для швидкого створення промісів, що миттєво успішно виконуються або відхиляються. Вони працюють аналогічно new Promise(), повертають проміс, але мають коротший синтаксис.
* Так створюється успішно виконаний проміс через Promise.resolve():
Promise.resolve("success value");
.then(value => console.log(value));
.catch(error => console.log(error));
* Так створюється проміс, що виконався з помилкою через Promise.reject():
Promise.reject("error");
.then(value => console.log(value));
.catch(error => console.log(error));
===== Promise.all() (Обробка множинних промісів) =====
Є ситуації, коли потрібно чекати на виконання всіх промісів одночасно, а потім обробляти їх результати. Або ситуації, коли достатньо дочекатися виконання хоча б одного з них, ігноруючи інші випадки. Для цих сценаріїв клас Promise має статичні методи для роботи з групою промісів.
Метод Promise.all() **дозволяє одночасно обробити кілька промісів та отримати їхні результати**. Він приймає масив промісів як вхідні дані, чекає їх виконання та повертає один проміс.
Якщо всі проміси виконуються успішно, повернений проміс перейде у стан fulfilled, а його значенням буде масив результатів виконання кожного промісу.
const p1 = Promise.resolve(1);
const p2 = Promise.resolve(2);
const p3 = Promise.resolve(3);
Promise.all([p1, p2, p3])
.then(values => console.log(values)); // [1, 2, 3]
.catch(error => console.log(error));
**якщо хоча б один з промісів відхиляється, повернений проміс одразу переходить у стан rejected, а його значенням буде помилка**.
===== Promise.allSettled() =====
Також дозволяє одночасно обробити кілька промісів та отримати їхні результати.
Відмінність від Promise.all полягає в тому, що метод Promise.allSettled() **чекає виконання всіх промісів незалежно від того, чи були деякі або навіть всі проміси відхилені**.
===== Promise.race =====
приймає масив промісів і повертає "найшвидший", тобто перший виконаний або відхилений проміс з переданих, разом зі значенням або причиною його відхилення.
const p1 = new Promise((resolve, reject) => {
setTimeout(() => resolve(1), 1000);
});
const p2 = new Promise((resolve, reject) => {
setTimeout(() => reject(2), 2000);
});
Promise.race([p1, p2])
.then(value => console.log(value)); // 1
.catch(error => console.log(error));
===== Іньші приклади =====
* Приклад 2 (web)
fetch('https://jsonplaceholder.typicode.com/todos')
.then(response => {
console.log(response) // показує поний склад відповіді від серверу (з тех.дннними)
return response.json() //поверта тільки данні після ковераації з json
})
.then(json => console.log(json))
.catch(error => console.log(error.message))
* Приклад 3 (node.js)
const getData =(url)=>
new Promise ((resolve, reject)=>
fetch(url)
.then(response=>response.json())
.then(json => resolve(json))
.catch(error=>reject(error))
)
getData('https://jsonplaceholder.typicode.com/todos')
.then(data=>console.log(data))
.catch(error=>console.log(error))