On designing asynchronous functions, I used to make them return a promise OR accept a callback function. I call this PoC.
I use package undertake to create a PoC asynchronous function:
const undertake = require('undertake');
const add = undertake.async(function*(a, b) {
// A promisified function.
let fa = function(a) {
return Promise.resolve(a);
};
// A traditional asynchronous function.
let fb = function(b, callback) {
// Here `null` means no exception happens.
callback(null, b);
};
let m = yield fa(a);
let n = yield fb(b);
let ret = m + n;
return ret;
});
// If no callback offered, a promise will be returned.
add(1, 2)
.then(data => {
// ...
}).catch(ex => {
// ...
});
// If callback found, it will be run.
add(1, 2, (ex, data) => {
if (ex) {
// ...
}
else {
// ...
}
});
Charged upon notorious Callback Hell, tranditional asynchrous functions accepting arguments list ended with a callback function are not welcome. Now in 2019, Promise and async / await become popular. Since Node.js version 8.0.0, offical method util.promisify(original) is released to help transforming a traditional asynchronous function to a promisified one.
- Sebastian Lindström, Getting to know asynchronous JavaScript: Callbacks, Promises and Async/Await, 2017.06.03
- Job Vranish, Never Mix Promises and Callbacks in NodeJS, 2017.04.06
- maxogden, Callback Hell, A guide to writing asynchronous JavaScript programs, updated at 2016.02.05