3.1 Створення ланцюжків промісів
Ланцюжки промісів дозволяють послідовно виконувати кілька асинхронних операцій, передаючи результат однієї операції до наступної. Це робить код більш читабельним і легким у підтримці. Крім того, проміси надають потужні можливості для обробки помилок, що дозволяє створювати надійні та стійкі до збоїв додатки.
Основна концепція
Ланцюжок промісів створюється шляхом повернення нового промісу з методу then. Кожен метод then повертає новий проміс, що дозволяє будувати послідовні асинхронні операції.
Приклад простого ланцюжка промісів
У цьому прикладі кожен метод then виконує свою операцію і передає результат наступному методу then.
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Крок 1 завершено');
}, 1000);
});
promise
.then((result) => {
console.log(result); // Виведе: Крок 1 завершено
return 'Крок 2 завершено';
})
.then((result) => {
console.log(result); // Виведе: Крок 2 завершено
return 'Крок 3 завершено';
})
.then((result) => {
console.log(result); // Виведе: Крок 3 завершено
})
.catch((error) => {
console.error(error);
});
Приклад ланцюжка з асинхронними операціями
У цьому прикладі кожен метод then чекає завершення асинхронної операції перед виконанням наступного кроку:
function asyncOperation(step) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`${step} завершено`);
}, 1000);
});
}
asyncOperation('Крок 1')
.then((result) => {
console.log(result); // Виведе: Крок 1 завершено
return asyncOperation('Крок 2');
})
.then((result) => {
console.log(result); // Виведе: Крок 2 завершено
return asyncOperation('Крок 3');
})
.then((result) => {
console.log(result); // Виведе: Крок 3 завершено
})
.catch((error) => {
console.error(error);
});
3.2 Обробка помилок у ланцюжках промісів
Метод catch використовується для обробки помилок у ланцюжку промісів. Якщо в будь-якому з промісів виникає помилка, вона передається до найближчого методу catch. Це дозволяє централізовано обробляти помилки, покращуючи читабельність і підтримку коду.
Приклад обробки помилок
У цьому прикладі помилка, що сталася у Кроці 2, перехоплюється методом catch, і подальші методи then не виконуються:
function asyncOperation(step, shouldFail = false) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (shouldFail) {
reject(`${step} провалено`);
} else {
resolve(`${step} завершено`);
}
}, 1000);
});
}
asyncOperation('Крок 1')
.then((result) => {
console.log(result);
return asyncOperation('Крок 2', true); // Ця операція завершиться помилкою
})
.then((result) => {
console.log(result); // Цей код не буде виконаний
return asyncOperation('Крок 3');
})
.then((result) => {
console.log(result); // Цей код не буде виконаний
})
.catch((error) => {
console.error('Помилка:', error); // Виведе: Помилка: Крок 2 провалено
});
Обробка помилок у конкретних кроках
Іноді потрібно обробляти помилки у конкретних кроках ланцюжка, не перериваючи виконання всього ланцюжка. Для цього можна використовувати вкладені методи then та catch.
Приклад обробки помилок у конкретних кроках
У цьому прикладі помилка у Кроці 2 обробляється локально, і ланцюжок продовжує виконуватись із відновленим значенням:
function asyncOperation(step, shouldFail = false) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (shouldFail) {
reject(`${step} провалено`);
} else {
resolve(`${step} завершено`);
}
}, 1000);
});
}
asyncOperation('Крок 1')
.then((result) => {
console.log(result);
return asyncOperation('Крок 2', true).catch((error) => {
console.warn('Оброблено помилку у Кроці 2:', error);
return 'Відновлено після помилки у Кроці 2';
});
})
.then((result) => {
console.log(result); // Виведе: Відновлено після помилки у Кроці 2
return asyncOperation('Крок 3');
})
.then((result) => {
console.log(result); // Виведе: Крок 3 завершено
})
.catch((error) => {
console.error('Помилка:', error); // Цей код не буде виконаний
});
3.3 Використання finally
Метод finally використовується для виконання коду незалежно від того, чи завершився проміс успішно, чи з помилкою. Це корисно для виконання завершальних дій, таких як очищення ресурсів.
Приклад використання finally:
function asyncOperation(step, shouldFail = false) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (shouldFail) {
reject(`${step} провалено`);
} else {
resolve(`${step} завершено`);
}
}, 1000);
});
}
asyncOperation('Крок 1')
.then((result) => {
console.log(result);
return asyncOperation('Крок 2');
})
.then((result) => {
console.log(result);
return asyncOperation('Крок 3');
})
.catch((error) => {
console.error('Помилка:', error);
})
.finally(() => {
console.log('Всі операції завершено'); // Буде виконано у будь-якому випадку
});
У цьому прикладі метод finally виконується у будь-якому випадку, незалежно від того, сталася помилка чи ні.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ