Как провести рефакторинг этой анонимной функции Javascript?

StackOverflow https://stackoverflow.com/questions/2542208

  •  23-09-2019
  •  | 
  •  

Вопрос

В нашем коде есть анонимная функция, которая является частью параметров объекта Ajax jQuery и использует некоторые переменные из функции, из которой она вызывается.

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;
            }
        }
   });
}

Я опустил дополнительный код, но вы поняли.Код работает отлично, но при каждом вызове в IE он теряет 4 КБ, поэтому я хочу провести его рефакторинг, чтобы превратить анонимную функцию в именованную, вот так.onSuccess = function(res) { ..}.

Проблема в том, что эта функция использует переменные из this.invoke(..), поэтому я не могу просто вынести ее за пределы ее тела.Как правильно провести рефакторинг этого кода, чтобы он не использовать анонимные функции и переменные родительских функций?

Обновлять. Я подумываю о создании отдельного объекта, инициализации его с теми же параметрами и передаче его функции onSuccess в качестве параметра для объекта Ajax jQuery.Хотя подозреваю, что все равно будет утечка памяти.

Обновление 2. Я нашел несколько ссылок, предполагающих, что фактическая утечка может быть вызвана jQuery.Простой вызов Ajax jQuery приводит к утечке памяти в Internet Explorer Утечка памяти, связанная с запросами jQuery Ajax

Тем не менее, было приятно найти способ реорганизовать это.

Обновление 3. Я подожду более общего решения, прежде чем принять ответ.

Это было полезно?

Решение

Вы можете добавить дополнительные параметры в запрос ajax, доступ к которым можно получить в обратном вызове успеха:

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;
    }
}

Другие советы

+1 за отличный, отличный вопрос — я чувствую вашу боль — это действительно хорошо учтено.

Одно предложение (и, возможно, именно это вы имели в виду под своим обновлением)... определите оболочку для onSuccess и заставьте ее возвращать функцию, которую вы хотите назначить.Затем вызовите внешнюю функцию и назначьте ее опции «успех», передав необходимые ей значения.Эти значения будут предварительно присвоены переменным во внутренней функции.На самом деле не уверен, поможет ли это — вы все равно получите анонимную функцию — но попробовать стоит.

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;
        }
     }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top