The sidebar helper

Okay! So of course, there's a catch, right!? Well, kind of. Since we introduced async in our Comments helper module, we now need to introduce it in our sidebar helper. This is because of the simple fact that our Comments helper is now really asynchronous, so anything that uses our Comments module needs to deal with that. As our sidebar module currently stands, it's just expecting the comments helper module to return an array instantly; so, it's not expecting to have to wait around for the actual data. Because of this, if we ran our code as is, our comments sidebar would remain blank (because the sidebar would have rendered the page before the MongoDB calls were even finished thinking within the comments module). Let's fix this by updating our sidebar helper module to use async as well.

First, let's edit the helpers/sidebar.js file and replace its entire contents with this slightly modified version that uses async.parallel:

const Stats = require('./stats'),
Images = require('./images'),
Comments = require('./comments'),
async = require('async');

module.exports = (viewModel, callback) => {
async.parallel([
(next) => {
next(null, Stats());
},
(next) => {
next(null, Images.popular());
},
(next) => {
Comments.newest(next);
}
], (err, results) => {
viewModel.sidebar = {
stats: results[0],
popular: results[1],
comments: results[2]
};

callback(viewModel);
});
};

The first thing we did was make sure async was included as a required module at the top of the file. Inside the primary exports function, we basically wrapped our existing code and integrated it into async.parallel so that we could easily tweak it a little later as we updated each section of the sidebar helpers. Since we've only completed the comments helper module so far, that's the only one that's actually been changed. The other Stats and Images.popular calls are being forcibly used with async.parallel, even though it doesn't quite make sense to do that right now. It will once those two sections become more asynchronous in the next sections.

The parallel function of async works in a similar way to its each function that we used earlier. The main difference is that parallel isn't performing the same function in a loop through a collection, but is instead performing a series of unique functions all at the same time. If you look closely, you can see that the first parameter to parallel is actually an array, and each item in the array is a unique function. Every function in the array accepts a next callback parameter function, which is executed at the conclusion of each of the functions. The second parameter in the next callback is the result of the work that was performed within the function itself. In the case of Stats and Images.popular, those two functions simply return values instantly, with no asynchronous calls to anything else, so we just expect the results to be returned by executing them directly.

However, as you can see with the Comments.newest section, we are passing in the next callback function as a parameter because we want its execution to be deferred until the last second (until Comments.newest has completed all of its work). Once that next callback function is called, it is passed the results of all of its work.

The last parameter to the parallel function is an inline function that accepts a results array as its second parameter. This array is a collection of the results that were returned from each of the functions in the array in the first parameter. You can see that when we build viewModel now, we are referring to indexes in the results array. The index order is the order that the functions were defined in the original array. We know that the first function was to retrieve Stats, the second function was to retrieve Images.popular, and the third function was to retrieve Comments.newest. So, we can reliably assign results[0] to viewModel.Stats, and so on. As a reference, here is what the viewModel definition originally looked like in the sidebar module:

viewModel.sidebar = {
stats: Stats(),
popular: Images.popular(),
comments: Comments.newest()
};

You can compare this with the updated version that uses async:

viewModel.sidebar = {
stats: results[0],
popular: results[1],
comments: results[2]
};

Now that the sidebar is set up to properly handle the helper modules that are (and eventually will be) asynchronous, we can run the application and test it to ensure that our sidebar is properly displaying the top five most recent comments on the website. Run the application and launch it in a browser. If you haven't already posted any comments to an image, do so now, so that you can see those comments appearing in the sidebar along with a thumbnail of the image they belong to.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.40.189