Reputation: 1680
I have a node issue. I want to call a Data Access Object and possibly other within it and once completed render a Jade template
Something like :
provider1.getData(args, function(error, results) {
/* do something with each result element */
for(int i = 0l i < results.length; i++) {
provider2.getData(args, function(error, items) {
store.push(items);
});
}
});
/* Here I want to ensure that the above operations are complete */
result.render( .... , {
data:store
});
Basically, I want to ensure that the data retrieval completes before I render a template with the data. At the moment, the variable store is not populated when the render occurs. I have looked at promises
which looks promising. Does anyone have a neat solution for converting my code example into a synchronous structure ?
Upvotes: 1
Views: 122
Reputation: 276276
Here is a promises answer (assuming Bluebird). I think it's a lot cleaner:
// convert to promise interface, it's possible to do this on a single method basis
// or an API basis, it depends on your case - it's also _very_ fast.
Promise.promisifyAll(Object.getPrototypeOf(provider1.prototype));
Promise.promisifyAll(Object.getPrototypeOf(provider2.prototype));
//note the async suffix is added by promisification.
provider1.getDataAsync(args).then(function(results) {
return Promise.map(results,provider2.getDataAsync.bind(provider2));
}).then(function(results){
//results array here, everything is done and ready,
});
As always with promises, if you have an error you can simply throw
.
Upvotes: 3
Reputation: 3669
You should try using async library.
provider1.getData(args, function(error, results) {
/* do something with each result element */
async.each(results,
function(result, cb) { // called for each item in results
provider2.getData(args, function(error, items) {
store.push(items);
cb(error);
});
},
// final callback
function (err) {
if (!err) {
/* Here I want to ensure that the above operations are complete */
result.render( .... , {
data:store
});
}
}
);
}
Upvotes: 0