Over a million developers have joined DZone.

Making Promises for a Better World

Dealing with callbacks in Node.js can be a bit cumbersome, and while Promises have been with us for some time, sometimes it's helpful to review the basics and some options. Read on to find out more.

· Web Dev Zone

Start coding today to experience the powerful engine that drives data application’s development, brought to you in partnership with Qlik.

Do you think that we can make our world better by making and keeping our promises? If you agree, keep reading! Just kidding. Actually, in this post, we’re going to see how we can build better software by making promises in Node.js.

Node is built with callback design pattern in mind. Large part of its APIs accepts a callback function as a second parameter. Callbacks are very easy to grasp. They have become the default way of handling async data flows in JavaScript. But its simplicity comes at a price. While callback function is fine for simple cases, it may causes a lot of issues in complex cases:

  • Callback hell
  • Inconsistent behavior ( releasing Zalgo) )
  • Misbehaving callbacks
    • Callbacks may be called many times
    • Callbacks may never be called
    • Callbacks may be called too early

And, Promises came to save us from callbacks. But, in Node, how can we make Promises from the callback world? By promisifying!

Almost all Promise libraries support an extra API allowing us to make a Promise version from callback version:

What “making a promise” functions do is to take an asynchronous operation that conforms to error-first style (or Node style) and wrap that into a Promise. Note that “making a promise” functions can’t convert a synchronous operation into a Promise based operation.

In following examples, we’re going to use bluebird to make Promises. By default, bluebird append the suffix “Async” to the callback based operation name when creating a Promise based version: method1 –> method1Async


const fs = require('fs')

fs.readFile('./data.zip', (err, content) => {
  if (err) {
      return errorHandler(err)


const Promise = require("bluebird")
const fs = Promise.promisifyAll(require("fs"))

  .then(content => console.log(content))


import mysql from "mysql";
const pool = mysql.createPool({..});

module.exports.execute = function(statement, params) {
    pool.getConnection(function(e, connection) {
        if(e) {
            return errorHandler(e);
        } else {            
            connection.query(statement, (e, results, fields) =>{
                if(e) {
                    return errorHandler(e);
                } else {


import mysql from "mysql";
import Promise from "bluebird";


const pool = mysql.createPool(config.dbConnectionPool);

 * API to execute a sql statement against the db.
export function execute (sql, params) {
    return Promise.using(getConnection(), (conn)=>{
        return conn.queryAsync(sql, params);

function getConnection(){
    return pool.getConnectionAsync().disposer((conn)=>{      

With Promises, our program is more clear by being closer to synchronous code, reducing nesting blocks and keeping track of less state.

Create data driven applications in Qlik’s free and easy to use coding environment, brought to you in partnership with Qlik.


Published at DZone with permission of Can Ho, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}