Alexandre Germain Alexandre Germain - 4 months ago 21
Javascript Question

Nodejs: Waterline + Caolan/Async: bind function

Using Balderdashy/Waterline and Caolan/Async, i'm trying to parallelize severa Waterline queries. Until now, the shorter I found is the following:

const tasks = {
foos: (function(){return this.exec.bind(this);}).apply(Foo.find({foo: "foo"})),
bars: (function(){return this.exec.bind(this);}).apply(Bar.find({bar: "bar"}))
};
return async.parallel(tasks, function(err, out){
// Here, err contains the potential error, and out looks like {foos:[...],bars:[...]}
});


I've tried to do
bars: Bar.find({bar: "bar"}).exec
but
async
seems to
apply
the function with another object as scope... So I can't find a way to do this in a shorter/simpler way.

Please note that I want to avoid wrapping the function in another by myself, as it is the syntax I want to find alternatives for:

bars: function(cb){Bar.find({bar: "bar"}).exec(cb)}


Thank you for your help.

Answer

Waterline’s Deferreds are thenables, so you can and should use them with promises. bluebird is an excellent implementation.

return bluebird.props({
    foos: Foo.find({foo: "foo"}),
    bars: Bar.find({bar: "bar"})
}).then(function (out) {
    // …
});

Yes, even if you want callbacks in general.

return bluebird.props({
    foos: Foo.find({foo: "foo"}),
    bars: Bar.find({bar: "bar"})
}).asCallback(function (err, out) {
    // …
});

If you have a very good reason for not being able to use promises despite Waterline already using them, I suppose you could attach something to the Deferred prototype:

var Deferred = require('waterline/lib/waterline/query/deferred').Deferred;

Object.defineProperty(Deferred.prototype, 'execBound', {
    configurable: true,
    get: function () {
        return this.exec.bind(this);
    }
});

used as:

const tasks = {
    foos: Foo.find({foo: "foo"}).execBound,
    bars: Bar.find({bar: "bar"}).execBound
};
return async.parallel(tasks, function(err, out){
    // Here, err contains the potential error, and out looks like {foos:[...],bars:[...]}
});
Comments