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