0

I am currently learning about bluebird and came up with this bit of code (Using Express.js and Mongoose) to test it out:

let startServer = Promise.promisify(app.listen, app);
let connectDB =  Promise.promisify(mongoose.connect, mongoose);

startServer(3000)
  .then(() => connectDB(MongoURI))
  .catch((e) => {
    console.log('Exception ' + e);
  });

The function in my first .then call is only returning another function. Therefore I was wondering, if there is a way to pass connectDB directly to .then and make it work. Something like this:

startServer(3000)
  .then(connectDB, MongoURI)
  .catch((e) => {
    console.log('Exception ' + e);
  });
MoeSattler
  • 6,684
  • 6
  • 24
  • 44

1 Answers1

3

Therefore I was wondering, if there is a way to pass connectDB directly to .then and make it work.

Yes, that's possible via something called currying (after Haskell Curry, the mathematician). You'll also see it called partial application. Basically, you create a new function that, when called, will call the original with the arguments you specify when creating it.

JavaScript has Function#bind which does two things: 1. Sets what this will be, and 2. Does currying. It doesn't look like your example cares what this will be, so we can use it for this.

Ex:

startServer(3000)
  .then(connectDB.bind(null, MongoURI))
  .catch((e) => {
    console.log('Exception ' + e);
  });

The null is for the thisArg argument, which we're effectively not using.

Here's a simpler example, just to illustrate:

function foo(a, b) {
  snippet.log("a = " + a);
  snippet.log("b = " + b);
}

// "Curry" 1 as the first arg
var f1 = foo.bind(null, 1);

// Call the resulting function:
f1(2); // "a = 1, b = 2"
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

Whether it's desireable is another question (and probably an opinion-based one). Your original with the arrow function is nice and clear and not likely to be expensive (in terms of memory or time). But it is possible to do ths, yes.


If you wanted the function to receive the this it was called with (probably not in your case, but it's fairly common in, say, jQuery event handlers in browser-based JavaScript), it's also easy to write a function that just does the currying without the this stuff Function#bind does. This answer has a very simple, un-optimized example.

Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875