Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is ".then(function(a){ return a; })" a no-op for promises?

I'm reading this tutorial about Bookshelf. Bookshelf uses Bluebird promises. There's quite a few examples that look something like this:

var getEvents = function(participantId) {  
  return new models.Participant()
    .query({where: {id: participantId}})
    .fetch({withRelated: ['events'], require: true})
    .then(function(model) {
      return model;
    });
};

I'm still not comfortable with promises, but from what I've learned so far this seems odd. My question is, is the above function exactly the same as returning fetch() directly and leaving off the final then():

var getEvents = function(participantId) {  
  return new models.Participant()
    .query({where: {id: participantId}})
    .fetch({withRelated: ['events'], require: true});
};

That is, it still does the same thing, returns the same promise, can be called in the same way, etc?

From what I understand, the parameter to the function passed to then gets the return value of the previous promise in the chain. So, it seems to me like .then(function (a) { return a; }) in general is just a no-op. Right?

If they aren't the same, what's the difference? What's going on and why did the author write it that way?

like image 277
Jason C Avatar asked Dec 11 '16 17:12

Jason C


2 Answers

It seems to me like .then(function (a) { return a; }) is just a no-op. Right?

Yes.1

It is useless and should be omitted.

What's going on and why did the author write it that way?

It's a blunder. Or the author didn't understand promises.

1: If they aren't the same, what's the difference?

As always, there are some edge cases. Really weird ones. That no-one should use (without extensive commenting):
a) it returns a new promise instance, a distinct object, to avoid sharing. However, .then() would as well.
b) a is tested again for its thenable-ness. If it suddenly became a promise since the fulfillment, it now will be awaited. This would be awful of course.

like image 60
Bergi Avatar answered Nov 10 '22 16:11

Bergi


Bergi's answer is right, but just to demonstrate a case where it's not a no-op here is a contrived example where it's not a no-op:

o = {};
Promise.resolve(o).then(o => o.then = () => {}); // make thenable
Promise.resolve(o).then(console.log); // logs the object
Promise.resolve(o).then(x => x).then(console.log); // doesn't log the object

In general, don't do then(function(a) { return a; })

like image 38
Benjamin Gruenbaum Avatar answered Nov 10 '22 16:11

Benjamin Gruenbaum