ПРОМИСИ

Виконання відкладених задач. Асінхронно.

Состояния промиса

ожидание (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))