简体   繁体   中英

Refactoring: returning a promise from a value or an existing promise

My scenario

I used to have some node.js implementation done using callbacks but I am now refactoring my code to use Promises instead - using Q module. I have the following update() function where the inner _update() function already returns a Promise :

exports.update = function(id, template, callback) {
  if (!_isValid(template)){
    return callback(new Error('Invalid data', Error.INVALID_DATA));
  }

  _update(id, template) // this already returns a promise
  .then(function() {
    console.log('UPDATE was OK!');
    callback();
  }, function(err) {
    console.log('UPDATE with ERRORs!');
    callback(err);
  });
};

My question

I would like to achieve something like the following :

exports.update = function(id, template) {
  if (!_isValid(template)){
    // how could I make it return a valid Promise Error?
    return reject(new Error('Invalid data', Error.INVALID_DATA));
  }

  return _update(id, template) // return the promise
  .done();
};

Because _update() already returns a promise , I guess changing it this way would be enough (wouldn't be?):

  return _update(id, template)
  .done();

And... what about if the condition inside the if-clause equals true ? How could I refactor

return callback(new Error('Invalid data', BaboonError.INVALID_DATA));

to throw an error to avoid passing the callback into update() and handling that error (or what ever error could ever be returning _update() )?

Also, calling update() :

myModule.update(someId, someTemplate)
.then(function() { /* if the promise returned ok, let's do something */ })
.catch(function(err) { /* wish to handle errors here if there was any */});

somewhere else in my code:

  • if there is an error during the promise propagation - it should handle it,
  • or, if there wasn't an error - it should do some other things

Am I close to what I am expecting? How could I finally achieve it?

I see only two problems.

  1. If you want to explicitly return a rejected promise with a value, you should do that with Q.reject .

  2. Calling .done() on promise means that the promise ends there. It cannot be chained further.

So, your code would look like this

exports.update = function (id, template) {
  if (!_isValid(template)) {
    return Q.reject(new Error('Invalid data', Error.INVALID_DATA));
  }

  return _update(id, template);
};

Now, the update function just returns a promise always. Its up to the callers to attach the success or failure handlers to it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM