Republicando: jQuery, de olho nos gaps

Estou republicando esse artigo pois o mesmo recebeu um comentário, e ao mesmo tempo, é um assunto que ainda assola muitas pessoas que utilizam jQuery, principalmente quem começou com ela há pouco tempo.

Qual webdeveloper nunca usou jQuery[bb]? Muito difícil… Bom, mas vamos falar de algo que nem todos os developers[bb] que usam jQuery se atentam ao programar. Eu mesmo fui pego hoje por um gap que me tomou alguns minutos da tarde…

Algumas funções (na verdade, a maioria nesse framework) recebem outras funções como callback, aquela função que será chamada assim que a instrução/função chamada acabar seu procedimento. Um exemplo muito utilizado em aplicações reais são as

Funções Ajax

load( url, data, callback )
Returns: jQuery. Load HTML from a remote file and inject it into the DOM.

jQuery.get( url, data, callback, type )
Returns: XMLHttpRequest. Load a remote page using an HTTP GET request.

jQuery.getJSON( url, data, callback )
Returns: XMLHttpRequest. Load JSON data using an HTTP GET request.

Ao usar a função load, você carrega um arquivo remoto (seja ele html puro ou um arquivo dinâmico, como PHP ou outra linguagem), mas o tempo que ele leva para ser processado nem sempre é igual. E se você precisa esperar que o conteúdo seja totalmente carregado antes de proceder com o script?Colocar um timeout? No way, uma vez que você não tem controle sobre o tempo de execução em todas as plataformas e clientes… Logo, o Callback está aí para sanar essa questão.

Porém…

Temos que tomar cuidado ao usar o Callback, uma vez que o desempenho dos sistemas ainda podem afetar a funcionalidade de seu código, e fazer você perder várias horas de seu precioso descanso…Veja esse trecho de código que trabalhei recentemente:

jQuery().ready(function() {
   jQuery.getJSON('/php/data.drafts.php?l=10&f=json', function(data){
      jQuery.each(data, function(i, item){
         jQuery('#latestDraftsTable tbody').append('<tr><td>'+item.id+'</td><td>' + item.title + '</td><td>' + item.date+ '</td></tr>');
      });
   });
   jQuery('#latestDraftsTable').tablesorter({widgets: ['zebra']});
);

Alguém consegue perceber o erro, ou melhor, a Zebra? Muito difícil. Mas ao rodar o código, não acontecia o esperado: que minha tabela apresentasse o comportamento de uma tabela ordenável que o jQuery UI tablesorter plugin proporciona (ou seja, deu Zebra e não ocorreu a Zebra). Aí eu descobri o problema: a penúltima linha do código nem estava sendo executada… Seriam Gaps de performance?

Diferentes paradigmas

Fosse uma linguagem das antigas qualquer, onde o paradigma procedural imperava, esse código não teria problema, pois cada instrução só seria disparada ao final da anterior. No Javascript, a coisa não é bem assim, ainda mais quando se trata de AJAX -Assynchronous Jacascript and XML – uma requisição que é disparada e outra estrutura interna fica encarregada de processar os resultados quando eles chegarem. Ao efetuar a função getJSON, a requisição é disparada, e já passamos para a próxima linha (onde eu chamo o tablesorter na tabela), porém, não deu tempo da requisição JSON retornar e popular a tabela. Resultado: minha tabela fica populada mas não fica ordenável.

Graças a um amigo developer fera em JS, eu consegui perceber isso e reordenaro código de maneira que ele funcionasse como o esperado:

Código corrigido

jQuery().ready(function() {
   jQuery.getJSON('/php/data.drafts.php?l=10&f=json', function(data){
      jQuery.each(data, function(i, item){
         jQuery('#latestDraftsTable tbody').append('<tr><td>'+item.id+'</td><td>' + item.title + '</td><td>' + item.date+ '</td></tr>');
      });
      jQuery('#latestDraftsTable').tablesorter({widgets: ['zebra']});
   });
);

Assim, o tablesorter vai ocorrer dentro do callback, logo após ter terminado de ser populada a tabela. Na realidade, os callbacks foram feitos exatamente para situações como essa: quando a coisa vai demorar um pouco e você não tem certeza do quanto…

3 ideias sobre “Republicando: jQuery, de olho nos gaps

  1. OI Thomas, eu me deparei com esse problema e desconfiei deste comportamento, e agora tenho a certeza lendo seu artigo. Muito bom, parabéns.

    Você tem alguma sugestão de workaround quando o retorno do callback precisa ser esperado, por exemplo, em combos aninhadas.
    Tenho três combos aninhadas, e quando escolho a primeira ela preenche a segunda, mas o evento da segunda já está disparando antes mesmo da combo finalizar a opçoes…

    Obrigado

    • Se você quer se referir a um arquivo no próprio servidor, é possível sim: basta você passar o caminho relativo dela ou até mesmo o absoluto (/arquivo.ext). Agora, se você quiser redirecionar o usuário para outra página, você pode usar

      window.location.href = '/arquivo.ext';

      Se ainda não for isso, me explica o que gostaria de fazer que vejo se posso ajudar.

Deixe uma resposta

O seu endereço de email não será publicado Campos obrigatórios são marcados *

*

Você pode usar estas tags e atributos de HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>