Skip to content
Related Articles

Related Articles

Promises in Node.js

Improve Article
Save Article
  • Difficulty Level : Medium
  • Last Updated : 26 Apr, 2022
Improve Article
Save Article

Introduction: Callback functions are used for Asynchronous events. Whenever any asynchronous event has to be taken place it is generally preferred to use callbacks (if data is not nested or inter-dependent).

Following is the simplest example where we could visualize how we may use a callback:-

Example: 

javascript




module.exports = (x, callback) => {
    if (x <= 0)
        setTimeout(() =>
            callback(new Error("Square dimensions
            should be greater than zero: s = " + x),
            null), 2000);
    else
        setTimeout(() =>
            callback(null, {
                perimeter: () => (4*(x)),
                area:() => (x*x)
            }), 2000);
}


What are Promises? A promise is basically an advancement of callbacks in Node.  In other words, a promise is a JavaScript object which is used to handle all the asynchronous data operations. While developing an application you may encounter that you are using a lot of nested callback functions. 

javascript




dboper.insertDocument(db, { name: "Test", description: "Test"},
    "test", (result) => {
        console.log("Insert Document:\n", result.ops);
 
        dboper.findDocuments(db, "test", (docs) => {
            console.log("Found Documents:\n", docs);
 
            dboper.updateDocument(db, { name: "Test" },
                { description: "Updated Test" }, "test",
                (result) => {
                    console.log("Updated Document:\n", result.result);
 
                    dboper.findDocuments(db, "test", (docs) => {
                        console.log("Found Updated Documents:\n", docs);
                             
                        db.dropCollection("test", (result) => {
                            console.log("Dropped Collection: ", result);
 
                            client.close();
                        });
                    });
                });
        });
    });


This is what happens due to the nesting of callback functions. Now imagine if you need to perform multiple nested operations like this. That would make your code messy and very complex. In Node.js world, this problem is called “Callback Hell”. To resolve this issue we need to get rid of the callback functions whilst nesting. This is where Promises come into the picture. A Promise in Node means an action which will either be completed or rejected. In case of completion, the promise is kept and otherwise, the promise is broken. So as the word suggests either the promise is kept or it is broken. And unlike callbacks, promises can be chained. 

Callbacks to Promises Promises notify whether the request is fulfilled or rejected. Callbacks can be registered with the .then() to handle fulfillment and rejection. The .then() can be chained to handle the fulfillment and rejection whereas .catch() can be used for handling the errors(if any).

 Example: 

javascript




dboper.insertDocument(db,
    { name: "Test", description: "Just a test"},
    "test").then((result) => {
        console.log("Insert Document:\n", result.ops);
    });


Nested Promises: Often you will encounter situations where you need to make use of nested Promises. Nested promises begin with a .then() and in each of the .then() we have a return statement. After the return statement, .then() follows in the same manner.  Following example shows the worst case scenario wherein multiple .then() methods are used in order to declare nested promises (which are dependent on each other for their own execution).

Example: 

javascript




MongoClient.connect(url).then((client) => {
 
    const db = client.db(database_name);
 
    database.insertDocument(db, { name: "Test",
        description: "Chill Out! Its just a test program!"},
        "test")
        .then((result) => {
            return database.findDocuments(db, "test");
        })
        .then((documents) => {
            console.log("Found Documents:\n", documents);
 
            return database.updateDocument(db, { name: "Test" },
                    { description: "Updated Test" }, "test");
        })
        .then((result) => {
            console.log("Updated Documents Found:\n", result.result);
 
            return database.findDocuments(db, "test");
        })
        .then((docs) => {
            console.log("The Updated Documents are:\n", docs);
                             
            return db.dropCollection("test");
        })
        .then((result) => {
             
            return client.close();
        })
        .catch((err) => alert(err));
 
})
.catch((err) => alert(err));


Now as compared to using the callbacks, our code looks a lot cleaner than before. As the .then() can be chained together, therefore every Promise is easy to identify in the code. The .catch(err) is executed if error(s) occurs. 

Creating custom Promises You can always create your own custom Promises in Node using the new constructor. 

Following example will help us to understand how we may create custom promises:-

Example:

javascript




var aPromise = new Promise(function(resolve, reject) {
    request.get(options, function(err, resp, body) {
        if (err) {
            reject(err);
        } else {
            resolve(JSON.parse(body));
        }
    })
});



My Personal Notes arrow_drop_up
Related Articles

Start Your Coding Journey Now!