Кратко
Промисификация — превращение callback-based функции в функцию, возвращающую Promise. Нужна при работе со старыми API (Node.js callbacks). В modern code (fetch, async/await) promisification встречается реже.
Подробно
Проблема: callback-based API
function loadData(url, onSuccess, onError) { // ... }
loadData(url, (data) => console.log(data), (error) => console.log(error) );
Решение: promisification
function loadDataAsync(url) { return new Promise((resolve, reject) => { loadData(url, resolve, reject); }); }
// Теперь: const data = await loadDataAsync(url);
Утилита promisify: function promisify(fn) { return function(...args) { return new Promise((resolve, reject) => { fn(...args, (error, result) => { if (error) reject(error); else resolve(result); }); }); }; }
// Использование: const loadDataP = promisify(loadData); const data = await loadDataP(url);
Node.js: const { promisify } = require('util'); const readFile = promisify(require('fs').readFile); const content = await readFile('file.txt', 'utf8');
Когда НЕ нужна:
- fetch() уже возвращает Promise
- async/await уже работают с Promises
- Современные API уже Promise-based
Ментальная модель
Промисификация — как переводчик с «callback-языка» на «Promise-язык». Старые API говорят на callback-языке («позвони мне, когда будет готово»). Промисификация переводит это на Promise-язык («жди результата»).
Примеры
**Самый простой:**
// Callback-based
function loadScript(src, callback) {
const script = document.createElement('script');
script.src = src;
script.onload = () => callback(null, script);
script.onerror = () => callback(new Error(`Failed: ${src}`));
document.head.append(script);
}
// Promisified
function loadScriptAsync(src) {
return new Promise((resolve, reject) => {
loadScript(src, (error, script) => {
if (error) reject(error);
else resolve(script);
});
});
}
await loadScriptAsync('/app.js');Промисификация callback-based loadScript.
**Простой:**
// Утилита promisify
function promisify(fn) {
return (...args) => new Promise((resolve, reject) => {
fn(...args, (err, result) => {
err ? reject(err) : resolve(result);
});
});
}
// Пример использования
function slowOperation(data, callback) {
setTimeout(() => callback(null, `Result: ${data}`), 1000);
}
const fast = promisify(slowOperation);
const result = await fast('test'); // 'Result: test'Универсальная утилита для промисификации.
**Реальный пример:**
// Node.js: промисификация fs
const fs = require('fs');
const { promisify } = require('util');
const readFile = promisify(fs.readFile);
const writeFile = promisify(fs.writeFile);
async function processFile(path) {
const content = await readFile(path, 'utf8');
const processed = content.toUpperCase();
await writeFile(path, processed);
console.log('Done!');
}Node.js: промисификация встроенных модулей.
Частые ошибки
**Неправильно:** Промисифицировать modern API
**Почему:** fetch, async/await, современные Node.js API уже возвращают Promises.
**Правильно:** Промисификация нужна только для callback-based legacy API.
**Неправильно:** Забывать обработать ошибки в promisify
**Почему:** Если callback не вызывается — Promise «зависает» навсегда.
**Правильно:** Убедитесь, что callback всегда вызывается (resolve или reject).
Важно запомнить
- Промисификация = callback → Promise
- Нужна для legacy callback-based API
- В modern code встречается реже
- Node.js: util.promisify
- Всегда обрабатывайте ошибки
Связь
Назад: Вы знаете Promise (JA4) и async/await (JA5). Промисификация соединяет старые API на колбэках с этим миром.
Вперёд: Следующий урок (JV11) — микрозадачи — порядок выполнения колбэков Promise.