I'm a C++/Python developer attempting to learn JavaScript, but I'm struggling to write clean code.  I've read that async.waterfall and Promises are two ways to flatten the code a bit, but my implementation seems far more inflated than what I've grown accustomed to using Python.  Is there anything that I can do to refactor the below code sample to compact it without failing to handle errors?nodejs Implementation:Authenticator.prototype.register = function(opts) {  var self = this;  return new Promise(function(resolve, reject) {    self.__validateIpAddress(opts.ip)    .then(function() {      self.__createRegisterAttempt(opts)      .then(function(attempt) {         // ...      }, function(err) {        reject(err);      }    }, function(err) {      reject(err);    });  });};Python Implementation: (for comparison)class Authenticator(object):    # caller must handle exceptions    def register(self, opts):        self.__validateIpAddress(opts['ip'])        attempt = self.__createRegisterAttempt(opts)        # ...
Validate IP address and create a registration attempt
javascript;beginner;error handling;authentication;promise
Creating a new promise when you already have a promise is considered a Promise anti-pattern.  Instead, you can just use the promise that is already available to you.  This then saves you all the reject handlers because if anywhere in the promise chain, there is a rejection that will propagate back.  So, I think you can just do this:Authenticator.prototype.register = function(opts) {  var self = this;  return  self.__validateIpAddress(opts.ip).then(function() {      self.__createRegisterAttempt(opts).then(function(attempt) {         // ...      });  });};