geralt @ pixelbay Every day that I work in JavaScript-land, I stumble across a mixture of callbacks, promises or async/await. I have my own preferences in how I like to handle async code, though sometimes I don’t have a choice because an external library like , , , etc. is using something else. fs serverless aws-sdk One thing I dislike in any codebase is inconsistency. So, if I start with promises, I’m going to use promises throughout. This presents one minor issue; how can I maintain consistency in a project that has external libraries. Well, as the title of this article suggests, I transform them. Callbacks and Promises The most common scenario I run into is an older library using node-style callbacks that I would prefer to use with promises, or async/await, same stuff. As a refresher, your typical node-style callback might look like this: fs.readFile('./kittens.txt', (err, data) => { if (err) throw err; console.log(data);}); But this is how I want to access the method: fs.readFile('./kittens.txt') .then(data => console.log(data)) Often, I just punt and use from . This is the easiest, fastest and approach. But… promisify bluebird.js laziest Importing a library to use but a single function is lazy and should be discouraged. … especially when the function in question would be simple to write. (google ) leftpad broke the internet Stop right now and take a look at the size of your node_modules folder. It’s obscene! It is not uncommon to have a node_modules folder in excess of 1GB or even 2GB! These things add up. Promisify What we want is called a . Function Decorator A is a higher-order function that takes one function as an argument, returns another function, and the returned function is a variation of the argument function. function decorator source Example of what a function decorator would look like: promisify const readFile = promisify(fs.readFile) readFile ('./kittens.txt') .then(data => console.log(data)) The function , still strongly related to , has been transformed into a variant of the original. This is a . readFile fs.readFile function decorator This should be easy to make. First we create the function that takes 1 argument, and returns a function. When that returned function is called it will return a promise. promisify func function promisify(func) {return () =>new Promise((resolve, reject) => { })} We used the keyword above because we will need access to , which is not available to arrow functions. function this Notice (below) how one additional argument, is appended to the end of . This is because our decorated function will not take a callback as an argument, but the original function does. callback args func func.apply(this, [...args, callback]) Put together it starts to look something like this: function promisify(func) {return ( ) =>new Promise((resolve, reject) => { ...args const callback = ??? **func.apply(this, \[...args, callback\]);** }) } The final step also happens to be the easiest, create the . The is simply a node-style that will call either or based on the presence of . callback callback callback resolve reject err Callbackify I ran into a less common situation where what I needed was the reverse. The function I had to create needed to be a node-style callback function. Uggg, my code was already written using promises. The code in question is for AWS lambdas, which are typically written using callbacks so my code ended up looking something like this: module.exports.handler function(event, context, ) {myHandler(event).then(data => ).catch(err => )} = callback callback(null, data) callback(err) Because my library is all Promise based, I would much prefer to write something like this: module.exports.handler = (event, context) =>myService(event) // note: I don’t need context. I ended up creating the reverse of , so I can create my lambda like this: promisify callbackify module.exports.handler = callbackify((event, context) =>myService(event)) Since we’re pretty much doing the same as above, we can zip through this a little quicker. Let’s create with a single argument, , that returns a function. Since the function that is returned will take args + callback as arguments, we are going to have to separate them from each other. callbackify func function callbackify(func) {return function(...args) { }} const onlyArgs = args.slice(0, args.length - 1)const callback = args[args.length - 1] Finally, we need to call on and pass in our . apply func onlyArgs How does async/await fit into all of this? async and await operates almost exactly like promises, so you can use them interchangeably. const readFile = promisify(fs.readFile)const file = await readFile('./kittens.txt) console.log(file) Check that out, you can await a node-style function. Neat! callback The Takeaways Whether you use callbacks, promises or async/await, it is most important to be consistent. Try creating your own functions before importing a library. If you want to tweak how a library function works, create a . function decorator Github I put these functions up on github so that I can easily import them into my projects as I use them in almost every project. You are welcome to use them as well. _functional-helpers — Functional helpers_github.com joelnet/functional-helpers Related util.promisify is being added to node bluebird’s promisify End If you found this interesting, or are interested in functional programming, you might enjoy some of my other articles. _Read the latest stories written by Joel Thoms on Medium. Computer Scientist and Technology Evangelist with 21 years of…_medium.com Latest stories written by Joel Thoms — Medium I know it’s a small thing, but it makes my day when I get those follow notifications on Medium and Twitter ( ). Or if you think I’m full of shit, tell me in the comments below. @joelnet Cheers!