Implementing Closure in Callbacks

An interesting problem related to asynchronous callbacks is closure. Closure is a JavaScript term that indicates that variables are bound to a function’s scope and not to the parent function’s scope. When you execute an asynchronous callback, the parent function’s scope may have changed (for example, when iterating through a list and altering values each iteration).

If a callback needs access to variables in the parent function’s scope, you need to provide closure so that those values are available when the callback is pulled off the event queue. A basic way of doing this is to encapsulate an asynchronous call inside a function block and pass in the variables that are needed.

The code in Listing 4.6 illustrates implementing a wrapper function that provides closure to the logCar() asynchronous function. Notice that the loop in lines 7–12 implements a basic callback. However, the output shown in Figure 4.9 shows that the car name is always the last item read because the value of message changes each time through the loop.

Image

Figure 4.9 Output of callback_closure.js, showing how adding a closure wrapper function allows the asynchronous callback to access necessary variables.

The loop in lines 13–20 implements a wrapper function that is passed message as the msg parameter, and the msg value sticks with the callback. Thus the closure output shown in Figure 4.9 displays the correct message. To make the callback truly asynchronous, you use the process.nextTick() method to schedule the callback.

Listing 4.6 callback_closure.js: Creating a wrapper function to provide closure for variables needed in the asynchronous callback


01 function logCar(logMsg, callback){
02   process.nextTick(function() {
03     callback(logMsg);
04   });
05 }
06 var cars = ["Ferrari", "Porsche", "Bugatti"];
07 for (var idx in cars){
08   var message = "Saw a " + cars[idx];
09   logCar(message, function(){
10     console.log("Normal Callback: " + message);
11   });
12 }
13 for (var idx in cars){
14   var message = "Saw a " + cars[idx];
15   (function(msg){
16     logCar(msg, function(){
17       console.log("Closure Callback: " + msg);
18     });
19   })(message);
20 }


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

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