views:

438

answers:

2

Suppose you want to make an async request in JavaScript, but you want to pass some state along to the callback method. Is the following an appropriate use of closures in JavaScript?

function getSomethingAsync(someState, callback) {
    var req = abc.createRequestObject(someParams);
    req.invoke(makeCallback(someState, callback));
}

function makeCallback(someState, callback) {
    return function getSomethingCallback(data) {
        var result = processDataUsingState(data, someState);
        callback(result); // alternately/optionally pass someState along to result
    }
}

If not, is there a better or more idiomatic way?

A: 

its better (nicer) to use anonymous functions:

function getSomethingAsync (someState, callback) {
    req.invoke (function (data) {
       var result = processDataUsingState (data, someState);
       callback (result);
    });
}
Javier
Javier...why is this better?Person who downvoted this...why is it not a good answer?
David Citron
simply to avoid red-tape: a function call and extra names just to create the closure when you can create it on the spot. remember that giving a name to a function is simply assigning it to a variable.
Javier
But giving something a name also provides semantics as well as reuse; while your simplification is definitely useful if his makeCallback() function isn't used anywhere else, if it is you would have to then duplicate code. Sometimes it helps readability to break things out into named functions.
Jason Bunting
+2  A: 

I don't see any immediate problems with this - closures are powerful for numerous reasons, one of which is removing the need to use global variables for state maintenance.

That said, the only thing you need to be wary of with regards to closures is memory leaks that typically occur in IE, but those are usually, IIRC, related to DOM elements and event handlers attached thereto.

Proceed!

Jason Bunting
Good point. Here's a discussion of the IE leak issue: http://laurens.vd.oever.nl/weblog/items2005/closures/
David Citron