Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to refactor this Javascript anonymous function?

We have this anonymous function in our code, which is part of the jQuery's Ajax object parameters and which uses some variables from the function it is called from.

this.invoke = function(method, data, callback, error, bare) {
      $.ajax({
        success: function(res) {
            if (!callback) return;

            var result = "";
            if (res != null && res.length != 0)
                var result = JSON2.parse(res);

            if (bare)
            { callback(result); return; }

            for (var property in result) {
                callback(result[property]);
                break;
            }
        }
   });
}

I have omitted the extra code, but you get the idea. The code works perfectly fine, but it leaks 4 Kbs on each call in IE, so I want to refactor it to turn the anonymous function into a named one, like this.onSuccess = function(res) { .. }.

The problem is that this function uses variables from this.invoke(..), so I cannot just take it outside of its body. How do I correctly refactor this code, so that it does not use anonymous functions and parent function variables?

Update. I am thinking of creating a separate object, initializing it with the same parameters, and pass its onSuccess function as a parameter for jQuery's Ajax object. Although I suspect that it will still leak memory.

Update 2. I have found a few links suggesting that the actual leak might be caused by jQuery. Simple jQuery Ajax call leaks memory in Internet Explorer Memory leak involving jQuery Ajax requests

Still it was good to find a way to refactor this.

Update 3. I will wait for a more generic solution, before accepting an answer.

like image 960
Egor Pavlikhin Avatar asked Mar 30 '10 00:03

Egor Pavlikhin


People also ask

How do you declare anonymous function in JavaScript?

Anonymous Function is a function that does not have any name associated with it. Normally we use the function keyword before the function name to define a function in JavaScript, however, in anonymous functions in JavaScript, we use only the function keyword without the function name.

Can anonymous function return JavaScript?

No, you cannot return a value from an asynchronous callback. Event callback will be called on click, but you can't assign its result.

How do we assign an anonymous function to a variable?

To turn a normal anonymous function into a self-executing function, you simply wrap the anonymous function in parentheses and add a set of parentheses and a semicolon after it. The benefit of using self-executing anonymous functions is that the variables you create inside of them are destroyed when the function exits.

How do you define an anonymous function?

An anonymous function is a function that is not stored in a program file, but is associated with a variable whose data type is function_handle . Anonymous functions can accept multiple inputs and return one output. They can contain only a single executable statement.

How do I call an anonymous function in JavaScript?

If you want to call the anonymous function later, assign the function to the say variable. We often use anonymous functions as arguments of other functions. In this example, we pass an anonymous function into the js setTimeout () function.

How do I pass an anonymous function as an argument?

We often use anonymous functions as arguments for other functions. For example: In this example, we pass an anonymous function into the setTimeout () function. The setTimeout () function executes this anonymous function one second later. Note that functions are the first-class citizens in JavaScript to pass a function to another as an argument.

What is anonymous function in C++?

As the name suggest of these function, An anonymous function is declared without any name. In this example, the anonymous function has without a name. It has assigned to a variable.

How do you pass a function to another function in JavaScript?

For example: In this example, we pass an anonymous function into the setTimeout () function. The setTimeout () function executes this anonymous function one second later. Note that functions are the first-class citizens in JavaScript to pass a function to another as an argument.


2 Answers

You can add extra params to the ajax request that can be accessed in the success callback:

this.invoke = function(method, data, callback, error, bare) {
    $.ajax({
        success: onSuccess,
        invokedata: {
         callback: callback,
         bare: bare
        }
    });
};

var onSuccess = function(res) {
    var callback = this.invokedata.callback,
        bare = this.invokedata.bare;
    if (!callback) return;

    var result = "";
    if (res != null && res.length != 0)
        var result = JSON2.parse(res);

    if (bare){
        callback(result); 
        return;
    }

    for (var property in result) {
        callback(result[property]);
        break;
    }
}
like image 137
PetersenDidIt Avatar answered Nov 10 '22 07:11

PetersenDidIt


+1 for excellent, excellent question - I feel your pain - this is really nicely factored as it is.

One suggestion (and maybe this is what you meant by your update)...define a wrapper for onSuccess and make it return the function you want to assign. Then call the outer function and assign it to the "success" option, passing the values it needs. Those values will be pre-assigned to the variables in the inner function. Not actually sure if this will help - you still end up with an anonymous function - but worth a try

this.invoke = function(method, data, callback, error, bare) {
    $.ajax({
        success: onSuccess(callback, bare);
    });
};

var onSuccess = function(callback, bare) {
     return function() {
        if (!callback) return;

        var result = "";
        if (res != null && res.length != 0)
            var result = JSON2.parse(res);

        if (bare)
        { callback(result); return; }

        for (var property in result) {
            callback(result[property]);
            break;
        }
     }
}
like image 33
plodder Avatar answered Nov 10 '22 06:11

plodder