Fetching user details, posts, and comments using promises in ExpressJS I'm creating an API service in NodeJS using Express (version 4) Framework. Created an MVC architecture for the same (no views, only model, and controller as this is an API).

Also, there are routes. When a request is made, the router redirects the request to the controller function and from there functions written in models are called and the response is returned to users in JSON format.

I gotta make multiple asynchronous requests from the controller for some functions. I earlier nested the asynchronous calls (callback hell) before I switched to Promises.

My NodeJS version is 6.12 and it does not support async/await.

I wanna make sure the way I implemented promises is correct. 

Here is a sample function from my controller using which I fetch user details.
The user passes a userID and using that I fetch user details. And using details from the 1st async request, I fetch user's posts and after that, I fetch user comments. I wanna make sure my implementation is correct.

Note: I removed error handling from some asynchronous requests to make the code look more understandable.

exports.fetchUserInformation = function (req, res) {
  var response = {};

  if (req.query.userId) {
    var userId = req.query.userId;
    response['userId'] = userId;
    new Promise(function (resolve, reject) {
      var param = {
        userId: userId
      };
      //1 - Call to Model function to fetch user info
      User.getUserDetails(param, function (err, rows) {
        if (err) {
          reject(err);
        } else {
          resolve(rows);
        }
      });
    }).then(function (result1) {
      var result2;
      response['userDetails'] = result1;

      //Pass result from previous promise to fetch next result
      var params1 = {
        userId: userId,
        result: result1
      };
      //2 - Call to Model function to fetch user timeline posts
      User.fetchUserPosts(params1, function (err, rows) {
        result2 = rows;
      });
    }).then(function (result2) {
      response['userPosts'] = result2;

      var params2 = {
        userId: userId,
        userType: 'user'
      };
      User.fetchUserComments(params2, function (err, rows) {

        response['userComments'] = rows;

        //return the response to user
        res.json({
          success: true,
          response: response
        });

      });
    }).catch(function (error) {
      //error logging starts
      var logData = {
        stackTrace: error
      };
      logHlpr.logThisError(logData); //calling another function to log data
      //error logging ends

      res.json({
        success: false
      });
    });
  }
};


I've few doubts:

I'm making 3 async requests to the Model - User.getUserDetails, User.fetchUserPosts, User.fetchUserComments using one promise. Should I implement 3 promises?

I'm pretty new to NodeJS and promises.
If you use 1 promise, you would encounter a long chain of then method and all of async operations would be executed in sequence style which increases response time.

If you create 3 promises, all of that can be performed in parallel. So the answer is yes, you should implement with 3 promises.

By the way, with help of bluebird library, You can write more readable JS code as I refactored show below, (I will explain more):

const bluebird = require('bluebird')
const User = require('./model/User')
bluebird.promisifyAll(User)

function asyncHandler(fn) {
    const promiseFn = bluebird.method(fn)
    return function(req, res) {
        let resultPromise = promiseFn.call(this, req,res)
        resultPromise.then(function(result) {
            res.json({
                success: true,
                response: result,
            })
        }).catch(function(err) {
            logHlpr.logThisError({stackTrace: err});
            res.json({
                success: false,
            })
        })
    }
}

exports.fetchUserInformation = asyncHandler(function(req, res) {
    if (!req.query.userId) {
        throw new Error("UserId is required")
    }
    let userId = req.query.userId
    let userDetails = User.getUserDetailsAsync({userId: userId})
    let userPosts = userDetails.then(result =&gt; User.fetchUserPostsAsync({userId: userId, result: result}))
    let userComments = User.fetchUserCommentsAsync({userId: userId, userType: 'user'})
    return bluebird.props({
        userId: userId,
        userDetails: userDetails,
        userPosts: userPosts,
        userComments: userComments,
    })
})


Most of the time, when you write JavaScript in Node.js, you need to work with callbacks, so convert all callback-style to promise-style by using bluebird.promisifyAll() or bluebird.promisify() will allow you to work with code easier, please see bluebird document.

After that most of handler function you write would deal with promise, so you can create higher-order function, like asyncHandler, which send success response in case that promise is fulfilled. You can also move asyncHandler function to shared-file and require() it later to use at multiple places.

For handler function, fetchUserInformation from your code sample, you want to return result as an object. This object contains result from many promises. You can use bluebird.props() which create a wrapper promise that wait all object's values to be fulfilled.

The last things, I would suggest you find a way to reimplement User.fetchUserPosts() that it wouldn't require userDetails as part of the parameter, so this method can be performed without waiting for User.getUserDetails() result and can make the code more elegant.