Как провести рефакторинг этой анонимной функции Javascript?
-
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;
}
}
}