Pergunta

Temos essa função anônima em nosso código, que faz parte dos parâmetros do objeto Ajax do jQuery e que utiliza algumas variáveis ​​da função de onde é chamada.

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

Omiti o código extra, mas você entendeu.O código funciona perfeitamente bem, mas vaza 4 Kbs em cada chamada no IE, então quero refatorá-lo para transformar a função anônima em uma função nomeada, como this.onSuccess = function(res) { ..}.

O problema é que esta função usa variáveis ​​de this.invoke(..), então não posso simplesmente tirá-la de seu corpo.Como refatorar corretamente esse código, para que ele não usar funções anônimas e variáveis ​​de função pai?

Atualizar. Estou pensando em criar um objeto separado, inicializá-lo com os mesmos parâmetros e passar sua função onSuccess como parâmetro para o objeto Ajax do jQuery.Embora eu suspeite que ainda haverá vazamento de memória.

Atualização 2. Encontrei alguns links sugerindo que o vazamento real pode ser causado pelo jQuery.Chamada jQuery Ajax simples vaza memória no Internet Explorer Vazamento de memória envolvendo solicitações jQuery Ajax

Ainda assim, foi bom encontrar uma maneira de refatorar isso.

Atualização 3. Vou esperar por uma solução mais genérica antes de aceitar uma resposta.

Foi útil?

Solução

Você pode adicionar parâmetros extras à solicitação ajax que podem ser acessados ​​no retorno de chamada de sucesso:

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

Outras dicas

+1 para uma pergunta excelente e excelente - sinto sua dor - isso já está muito bem contabilizado.

Uma sugestão (e talvez seja isso que você quis dizer com sua atualização)... defina um wrapper para onSuccess e faça com que ele retorne a função que você deseja atribuir.Em seguida, chame a função externa e atribua-a à opção "sucesso", passando os valores necessários.Esses valores serão pré-atribuídos às variáveis ​​na função interna.Na verdade, não tenho certeza se isso vai ajudar - você ainda terá uma função anônima - mas vale a pena tentar

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;
        }
     }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top