2016-08-04 93 views
1

使用Balderdashy/WaterlineCaolan/Async,我試圖並行化severa Waterline查詢。到現在爲止,我發現越短如下:Nodejs:Waterline + Caolan/Async:綁定函數

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:[...]} 
}); 

我試圖做bars: Bar.find({bar: "bar"}).execasync似乎apply與另一個對象範圍的功能。所以我無法找到一個方法來做到這在一個更簡單/更簡單的方式。

請注意,我想避免自己包裹在其他的功能,因爲它是我要找到替代的語法:

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

謝謝您的幫助。

回答

2

水線的Deferred s爲thenables,這樣你就可以和應該承諾使用它們。 bluebird是一個很好的實現。

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

是的,即使你想要一般的回調。

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

如果你有一個很好的理由不能夠不顧水線已經使用了他們使用的承諾,我想你可以附加一些東西到Deferred原型:

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

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

用作:

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:[...]} 
}); 
+0

這幾乎是我需要什麼?如果只是出結果可能會與比任務相同密鑰的dictionnary返回,這將是絕對完美的。 –

+0

@AlexandreGermain:'bluebird.props({foos:...,bars:...})'代替'Promise.all',然後。 (見編輯!) – Ryan

+0

哦,是的,你是對的。 Bluebird和延期工作都像一個魅力,非常感謝你! –