How would "this" behave normally within nested async module functions?

80 Views Asked by At

I'm using Sails.js framework and its great Model's feature, also I'm using the async version it uses as its dependency.

So, in order of explaining a practical scenario: get all comments on songs sung by an artist. I should first query the songs and then, query against comments.

This why I'm using async module, in particular its waterfall function. But as all this code is placed at a Model file, where this refers to the model itself, I got one big doubt:

Will this always refer to the model even when present inside async functions?

This is a code example of what I'm doing:

module.exports = {
  connection: 'seasonDB',
  attributes: {

    reachesMaxFavoriteTeam: function (team) {

      var results [];

      async.waterfall([

          // Get favorite team
          function (cb) {
              var userTeam = this.userTeam;

              UserTeam.findOne({_id: userTeam}, function (err, foundUserTeam) {
                  if (err)
                      cb(err,null);
                  var user = foundUserTeam.user;
                  User.find({_id: user}, {_id:false, fanOf: true}, function (err, fanOf) {
                      if (err)
                          cb(err,null);
                      cb(null,fanOf.name);
                  });
              });
          },
          // Check if it reaches a max favorite team error
          function (favoriteTeam,cb) {

              // If player to be added is from favorite team, it counts.
              favoriteCount = team === favoriteTeam ? 1: 0;

              // Check if any of added players are from favorite team too.
              _.forEach(this.players, function (player) {

                  var playerTeam = player.team.name;

                  if (playerTeam === favoriteTeam)
                      favoriteCount++;
              });


              return favoriteCount > process.env.CONDITION;
          }]);
    }
};

So, for example, at the first function in waterfall series I got: var userTeam = this.userTeam;, will this work as expected? Should I take care of something in case of other nested functions?

1

There are 1 best solutions below

4
On BEST ANSWER

Why don't you use Promises in those queries will make it so much easier to work with. I wouldn't use async, using Promises should do the job.

The underlying ORM module in Sails is Waterline. You can refer to Chaining waterline calls with Promises for an example or the GitHub page https://github.com/balderdashy/waterline which shows the below example,

User.findOne()
.where({ id: 2 })
.then(function(user){
    var comments = Comment.find({userId: user.id}).then(function(comments){
        return comments;
    });
   return [user.id, user.friendsList, comments];
}).spread(function(userId, friendsList, comments){
// Promises are awesome!
}).catch(function(err){
// An error occurred
})

Waterline-docs is also helpful for reference: https://github.com/balderdashy/waterline-docs