in bluebird / bookshelf.js what does tap function do

According to Reg “Raganwald” Braithwaite,

tap is a traditional name borrowed from various Unix shell commands. It takes a value and returns a function that always returns the value, but if you pass it a function, it executes the function for side-effects. [source]

Here is the same question being posed regarding underscore.js.

The gist is this: all tap does is return the object it was passed. However, if it is passed a function, it will execute that function. So, it is useful for debugging or for executing side-effects within an existing chain without altering that chain.


Bookshelf uses Bluebird for their promises, and I believe .tap() is one of their specific Promise methods. Looks like it allows you to essentially call a .then() without altering the value being passed through the chain.

http://bluebirdjs.com/docs/api/tap.html

Here is an example of the difference between Promise#tap() and Promise#then(). Note that Promise#tap() is not standard, and is Bluebird-specific.

var Promise = require('bluebird');

function getUser() {
  return new Promise(function(resolve, reject) {
    var user = {
      _id: 12345,
      username: 'test',
      email: '[email protected]'
    };
    resolve(user);
  });
}

getUser()
  .then(function(user) {
    // do something with `user`
    console.log('user in then #1:', user);
    // make sure we return `user` from `#then()`,
    // so it becomes available to the next promise method
    return user;
  })
  .tap(function(user) {
    console.log('user in tap:', user);
    // note that we are NOT returning `user` here,
    // because we don't need to with `#tap()`
  })
  .then(function(user) {
    // and that `user` is still available here,
    // thanks to using `#tap()`
    console.log('user in then #2:', user);
  })
  .then(function(user) {
    // note that `user` here will be `undefined`,
    // because we didn't return it from the previous `#then()`
    console.log('user in then #3:', user);
  });