Промисификация

30-06-24 16:31:05


Image for the Промисификация

Почему промисификация?

Традиционные функции на основе коллбеков часто приводят к callback hell, где вложенные коллбеки делают код трудным для чтения и поддержки. Промисы и синтаксис async/await помогают смягчить эти проблемы, предоставляя более чистый и линейный подход к асинхронному коду.

Преимущества промисификации:

  1. Читаемость: Промисы предоставляют линейную структуру, улучшая читаемость кода.
  2. Обработка ошибок: Промисы позволяют централизованно обрабатывать ошибки с помощью .catch().
  3. Цепочки: Промисы поддерживают цепочки, что облегчает обработку последовательных асинхронных операций.
  4. Совместимость: Промисы хорошо работают с современными функциями JavaScript, такими как async/await.

Как промисифицировать функцию

Промисификация функции включает в себя оборачивание функции на основе коллбеков в новую функцию, которая возвращает промис. Вот пошаговое руководство по промисификации функции. Рассмотрим типичную асинхронную функцию на основе коллбеков:

function fetchData(callback) {
setTimeout(() => {
const data = { user: 'John Doe' };
callback(null, data);
}, 1000);
}

Мы можем промисифицировать эту функцию следующим образом:

function fetchDataPromise() {
return new Promise((resolve, reject) => {
fetchData((error, data) => {
if (error) {
reject(error);
} else {
resolve(data);
}
});
});
}

// Использование промисифицированной функции
fetchDataPromise()
.then(data => {
console.log(data); // Вывод: { user: 'John Doe' }
})
.catch(error => {
console.error(error);
});

Утилита для промисификации

Чтобы избежать ручной промисификации каждой функции, мы можем создать утилитную функцию, которая промисифицирует любую функцию на основе коллбеков. Эту утилитную функцию можно использовать в разных частях приложения.

function promisify(func) {
return function(...args) {
return new Promise((resolve, reject) => {
func(...args, (error, result) => {
if (error) {
reject(error);
} else {
resolve(result);
}
});
});
};
}

// Пример функции на основе коллбеков
function getUserData(userId, callback) {
setTimeout(() => {
if (userId) {
callback(null, { id: userId, name: 'John Doe' });
} else {
callback('User not found');
}
}, 1000);
}

// Промисификация функции
const getUserDataPromise = promisify(getUserData);

// Использование промисифицированной функции
getUserDataPromise(1)
.then(user => {
console.log(user); // Вывод: { id: 1, name: 'John Doe' }
})
.catch(error => {
console.error(error);
});

Использование промисифицированных функций с async/await

Промисифицированные функции легко интегрируются с синтаксисом async/await, что еще больше улучшает читаемость и простоту кода.

async function fetchUserData(userId) {
try {
const user = await getUserDataPromise(userId);
console.log(user); // Вывод: { id: userId, name: 'John Doe' }
} catch (error) {
console.error(error);
}
}

fetchUserData(1);