How can I call Function.prototype.bind with an array of arguments, as opposed to hardcoded arguments? (Not using ECMA6, so no spread operator).
I'm trying to put a promises wrapper around a module that uses callbacks and I want to bind all of the arguments passed in to my wrapper method and bind them. Then I want to call the partially applied bound function with my own callback, which will resolve or reject a promise.
var find = function() {
var deferred, bound;
deferred = Q.defer();
bound = db.find.bind(null, arguments);
bound(function(err, docs) {
if(err) {
deferred.fail(err);
} else {
deferred.resolve(docs);
}
});
return deferred.promise;
}
But obviously this doesn't work because bind expects arguments rather than an array of arguments. I know I could do this by inserting my callback onto the end of the arguments array and using apply:
arguments[arguments.length] = function(err, docs) { ... }
db.find.apply(null, arguments);
Or by iterating over the arguments array and rebinding the function for each argument:
var bound, context;
for(var i = 0; i < arguments.length; i++) {
context = bound ? bound : db.find;
bound = context.bind(null, arguments[i]);
}
bound(function(err, docs) { ... })
But both of these methods feel dirty. Any ideas?
If someone is looking for an abstract sample:
Why not simply bind to the arguments array as per your example, and have the
bound()
function treat it just like that, as an array?By the looks of your usage, you are then passing in a function as the final argument to
bound()
, which means by passing in the actual argument array, you avoid having to separate arguments from callbacks insidebound()
, potentially making it easier to play with.For those using ES6, Babel compiles:
to:
I think it's fair to say Babel is pretty definitive. Credit to @lorenz-lo-sauer though, it's almost identical.
A definitive and simple answer might be
Kinda "hard" to grasp, yet, neat.
The following is a common snippet of code I use in all my projects:
The
bindable
function can now be used to pass an array tobind
as follows:In fact you can cache
bindable(db.find, db)
to speed up the binding as follows:You can use the
findable
function with or without an array of arguments:Hope this helps.
I find following cleaner than the accepted answers