Olá pessoal, blz?

Ao implementar uma busca, que precisava fazer uma requisição ao servidor, queria que fosse feita uma requisição a cada tecla que o usuário digitasse dentro do campo de busca. Bom, fiz isso e ficou uma bosta!

Tentando melhorar essa implementação, resolvi fazer a requisição somente quando o usuário terminasse de digitar o que ele estava querendo usar como filtro na busca. Mas, como saber que ele já terminou de digitar? Acredito que seja impossível de se ter com exatidão essa informação, embora podemos tentar deduzir. Veja como fiz isso.

 Deduzindo que o usuário parou de digitar em um input text

[sourcecode language="javascript"]
//Snippet 1
(function () {
$('#filtroDeBusca').keyup(function () {
setTimeout(funcaoQueRealizaBusca, 1000);
});
})();
[/sourcecode

No Snippet 1, criei um escopo com um listener para o evento keyup do filtro de busca em questão. A cada tecla pressionada dentro desse filtro, uso o setTimeout, um temporizador que executa um callback após determinado tempo, nesse caso o callback é a funcaoQueRealizaBusca e o tempo é 1 segundo.

A solução apresentada no Snippet 1 não funcionou muito bem, pois, toda vez que o evento keyup do filtroDeBusca era executado, uma nova requisição era feita ao servidor e esse era o problema inicial.

Para resolver, antes do setar o setTimeout bastava cancelar o que havia sido "agendado" anteriormente para que não fosse executado e isso é bem simples de se fazer. Veja como ficou essa implementação no Snippet 2.

[sourcecode language="javascript"]
//Snippet2
(function () {
$('#filtroDeBusca').keyup(function () {
clearTimeout(this.interval);
this.interval = setTimeout(funcaoQueRealizaBusca, 1000);
});
})();
[/sourcecode]

Antes de setar o setTimeout uso o clearTimeout, que recebe o id do "agendamento" que você quer cancelar. Como conseguir esse id? O setTimeout retorna para você. No Snippet 2 armazeno esse id dentro de uma propriedade que chamei de interval, ou seja, na próxima vez que o keyup for acionado, o id do setTimeout da execução anterior estará armazenado nessa propriedade.

Com isso, se o usuário começar a digitar no filtro e parar por um segundo, deduzo que ele terminou de digitar e a busca é iniciada.

Problema: E se o usuário digitar devagar? Paciência, serão realizadas mais requisições.

Conhece alguma outra forma de implementar essa solução? Deixe um comentário.

Para conhecer mais sobre temporizadores no javascript, recomendo a leitura do artigo Usando termporizadores like a ninja.

Até o próximo post!