Вопрос проверяет умение модернизировать устаревший асинхронный код, использующий колбэки, на современные конструкции ES6, что критично для повышения читаемости и управляемости кода.
Переход от колбэков к промисам и async/await — это ключевой шаг в модернизации JavaScript-кода. Колбэки приводят к вложенным структурам ("callback hell"), которые сложно читать и поддерживать. Промисы предоставляют более структурированный способ обработки асинхронных операций, а async/await делает код линейным и интуитивно понятным.
Любую функцию, которая использует колбэк в стиле (error, result) => {}, можно обернуть в промис. Это создаёт основу для дальнейших преобразований.
// Исходная функция с колбэком
function readFileCallback(path, callback) {
// Имитация асинхронного чтения
setTimeout(() => {
const data = 'file content';
callback(null, data); // Первый аргумент — ошибка
}, 100);
}
// Обёртка в промис
function readFilePromise(path) {
return new Promise((resolve, reject) => {
readFileCallback(path, (err, data) => {
if (err) reject(err);
else resolve(data);
});
});
}Вместо вложенных колбэков используйте методы .then() и .catch(). Это делает поток выполнения более явным.
// Колбэк-версия (плохо)
readFileCallback('file1.txt', (err, data1) => {
if (err) console.error(err);
else {
processData(data1, (err, result) => {
if (err) console.error(err);
else console.log(result);
});
}
});
// Промис-версия (лучше)
readFilePromise('file1.txt')
.then(data1 => processDataPromise(data1))
.then(result => console.log(result))
.catch(err => console.error(err));Ключевые слова async и await позволяют работать с промисами так, будто это синхронный код. Функция, объявленная как async, всегда возвращает промис, а await приостанавливает выполнение до разрешения промиса.
// async/await версия (наиболее читаемая)
async function processFiles() {
try {
const data1 = await readFilePromise('file1.txt');
const result = await processDataPromise(data1);
console.log(result);
} catch (err) {
console.error(err);
}
}
processFiles();Этот подход используется везде, где есть асинхронные операции: работа с файловой системой в Node.js, сетевые запросы (API), взаимодействие с базами данных, таймеры. Современные библиотеки (например, для HTTP или баз данных) часто уже возвращают промисы, но legacy-код или некоторые нативные API Node.js (например, fs.readFile без промисов) требуют такой конвертации.
Вывод: Переписывайте callback-based код на async/await для повышения читаемости, упрощения обработки ошибок (через try/catch) и облегчения поддержки. Это особенно полезно в больших проектах, где важна ясность логики потока выполнения.