function promisify(original) {
return function(...args) {
return new Promise((resolve, reject) => {
original.call(this, ...args, (err, result) => {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
};
}
const fs = require('fs');
const readFilePromise = promisify(fs.readFile);
readFilePromise('file.txt', 'utf8')
.then(data => console.log(data))
.catch(err => console.error(err));
function advancedPromisify(original) {
return function(...args) {
return new Promise((resolve, reject) => {
original.call(this, ...args, (err, ...results) => {
if (err) {
reject(err);
} else {
resolve(results.length > 1 ? results : results[0]);
}
});
});
};
}
function callbackify(promiseFn) {
return function(...args) {
const callback = args.pop();
if (typeof callback !== 'function') {
throw new TypeError('Callback must be a function');
}
promiseFn.apply(this, args)
.then(result => callback(null, result))
.catch(err => callback(err));
};
}
async function asyncFetchData(url) {
// Реализация с async/await
}
const callbackFetchData = callbackify(asyncFetchData);
callbackFetchData('https://api.example.com', (err, data) => {
if (err) return console.error(err);
console.log(data);
});
function advancedCallbackify(promiseFn) {
return function(...args) {
const callback = args.pop();
if (typeof callback !== 'function') {
return promiseFn.apply(this, args);
}
try {
const result = promiseFn.apply(this, args);
if (result && typeof result.then === 'function') {
result.then(
val => callback(null, val),
err => callback(err)
} else {
callback(null, result);
}
} catch (err) {
callback(err);
}
};
}
Node.js уже включает эти утилиты в модуле util
:
const { promisify } = require('util');
const sleep = promisify(setTimeout);
await sleep(1000); // Ждет 1 секунду
const { callbackify } = require('util');
const callbackAsyncFn = callbackify(asyncFn);
Обработка контекста:
this
при вызове оригинальной функции.call(this, ...)
или .apply(this, ...)
Множественные аргументы:
Ошибки:
Производительность:
promisify:
callbackify:
Лучшие практики:
util
Эти адаптеры позволяют плавно мигрировать между разными стилями асинхронного кода и интегрировать старые API с современными async/await подходами.