Resumo : neste tutorial, você aprenderá sobre a função debounce do JavaScript e como usá-la para melhorar o desempenho do aplicativo.
Para entender a função debounce, você criará um aplicativo de pesquisa da Wikipédia usando a técnica de programação debounce.
Crie a estrutura de pastas do projeto
Primeiro, crie uma nova pasta chamada wikipedia-search
que irá armazenar os arquivos dos projetos.
Segundo, crie três pastas dentro da wikipedia-search
pasta chamada js
, css
e img
. Essas pastas armazenarão arquivos JavaScript, CSS e imagens de acordo.
Terceiro, crie o style.css
na css
pasta e no app.js
também js
, baixe a imagem a seguir e copie-a para a img
pasta. Você usará o logotipo para criar a interface do aplicativo.
Finalmente, crie um index.html
arquivo na pasta raiz.
A estrutura do projeto ficará assim:
Construa a página HTML
Abra o arquivo index.html e adicione o seguinte código:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Wikipedia Search</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<header>
<img src="./img/wikipedia-logo.png" alt="wikipedia">
<h1>Wikipedia Search</h1>
<input type="text" name="searchTerm" id="searchTerm" placeholder="Enter a search term...">
</header>
<main id="searchResult"></main>
<script src="js/app.js"></script>
</body>
</html>
Linguagem de código: HTML, XML ( xml )
Neste arquivo HTML:
- Primeiro, crie um link para o
style.css
arquivo na<head>
seção. - Segundo, adicione uma
<script>
tagsrc
vinculada aoapp.js
arquivo e coloque-a logo antes da</body>
tag. - Terceiro, adicione duas seções ao corpo da página HTML. A primeira seção é o cabeçalho que mostra o logotipo da Wikipedia, o título e a caixa de pesquisa. A segunda seção inclui a
<main>
tag que exibirá o resultado da pesquisa.
Copie o código CSS
Navegue até o arquivo style.css , copie seu código e cole-o no style.css
arquivo da css
pasta. Ao abrir o index.html
arquivo, você deverá ver algo como a página a seguir .
Lidar com eventos de entrada
Primeiro, selecione os <input>
elementos do resultado da pesquisa usando o querySelector()
método:
const searchTermElem = document.querySelector('#searchTerm');
const searchResultElem = document.querySelector('#searchResult');
Linguagem de código: JavaScript ( javascript )
Segundo, defina o foco no <input>
elemento chamando o focus()
método:
searchTermElem.focus();
Linguagem de código: CSS ( css )
Terceiro, anexe um input
ouvinte de evento para o <input>
elemento:
searchTermElem.addEventListener('input', function (event) {
console.log(event.target.value);
});
Linguagem de código: JavaScript ( javascript )
Se você digitar algum texto no <input>
elemento, verá que input
ocorre o evento, que mostra o texto para o Console.
Por exemplo, quando você digita the debounce
no <input>
elemento:
… você verá os seguintes textos no console:
Obtenha resultados de pesquisa usando a API Wikipedia
A API da Wikipedia é bastante simples. Não requer uma chave de API.
Para obter os tópicos por um termo de pesquisa, você precisa anexar o srsearch
parâmetro de consulta:
&srsearch=<searchTerm>
Linguagem de código: HTML, XML ( xml )
para o seguinte URL:
https://en.wikipedia.org/w/api.php?action=query&list=search&prop=info|extracts&inprop=url&utf8=&format=json&origin=*&srlimit=10
Linguagem de código: JavaScript ( javascript )
… e envie uma GET
solicitação HTTP.
Por exemplo, você pode obter os tópicos relacionados à debounce
palavra-chave enviando uma GET
solicitação HTTP para o seguinte URL:
https://en.wikipedia.org/w/api.php?action=query&list=search&prop=info|extracts&inprop=url&utf8=&format=json&origin=*&srlimit=10&srsearch=debounce
Linguagem de código: JavaScript ( javascript )
A propósito, você pode abrir o URL acima no navegador para ver a resposta.
Em JavaScript, você pode usar a API fetch , que está disponível em todos os navegadores modernos, para enviar uma GET
solicitação HTTP.
O seguinte cria a search()
função que aceita um termo de pesquisa, faz uma GET
solicitação HTTP para a Wikipedia e mostra os resultados da pesquisa para o Console:
const search = async (searchTerm) => {
try {
const url = `https://en.wikipedia.org/w/api.php?action=query&list=search&prop=info|extracts&inprop=url&utf8=&format=json&origin=*&srlimit=10&srsearch=${searchTerm}`;
const response = await fetch(url);
const searchResults = await response.json();
// show the search result in the console
console.log({
'term': searchTerm,
'results': searchResults.query.search
});
} catch (error) {
console.log(error);
}
}
Linguagem de código: JavaScript ( javascript )
Como funciona.
Primeiro, construa o URL da API adicionando o srsearch
parâmetro de consulta ao endpoint:
const url = `https://en.wikipedia.org/w/api.php?action=query&list=search&prop=info|extracts&inprop=url&utf8=&format=json&origin=*&srlimit=10&srsearch=${searchTerm}`;
Linguagem de código: JavaScript ( javascript )
Segundo, use o fetch()
método para enviar uma GET
solicitação HTTP. Como o fetch()
método retorna uma promessa, você precisa usar await
uma palavra-chave para aguardar a resposta.
A promessa retornada pela fetch()
função possui muitos métodos, um deles é json()
. O json()
método também retorna outra promessa que resulta em um resultado no formato JSON.
Por causa da await
palavra-chave, você precisa marcar a search()
função async
como esta:
const search = async (searchTerm) = {
/// ...
};
Linguagem de código: JavaScript ( javascript )
O objeto retornado do json()
método possui muitas propriedades. E para obter os resultados da pesquisa, você precisa acessar o searchResults.query.search
imóvel.
Para testar o search()
método, chame-o no input
ouvinte de eventos da seguinte maneira:
searchTermElem.addEventListener('input', function (event) {
search(event.target.value);
});
Linguagem de código: JavaScript ( javascript )
A seguir mostra o app.js
arquivo completo:
const searchTermElem = document.querySelector('#searchTerm');
const searchResultElem = document.querySelector('#searchResult');
searchTermElem.select();
searchTermElem.addEventListener('input', function (event) {
search(event.target.value);
});
const search = async (searchTerm) => {
try {
const url = `https://en.wikipedia.org/w/api.php?action=query&list=search&prop=info|extracts&inprop=url&utf8=&format=json&origin=*&srlimit=10&srsearch=${searchTerm}`;
const response = await fetch(url);
const searchResults = await response.json();
// show the search result in the console
console.log({
'term': searchTerm,
'results': searchResults.query.search
});
} catch (error) {
console.log(error);
}
}
Linguagem de código: JavaScript ( javascript )
Agora, se você abrir o index.html
arquivo e digitar a debounce
palavra-chave no elemento input, verá os seguintes resultados no Console:
A saída indica que a search()
função é executada para cada caractere digitado. Chama a API para cada entrada de texto, o que não é eficiente.
Para limitar o número de solicitações, você enviará solicitações de API somente quando necessário. Em outras palavras, você enviará uma solicitação de API somente depois que os usuários pausarem ou pararem de digitar por um período de tempo, por exemplo, meio segundo.
Para fazer isso, você pode usar setTimeout() e clearTimeout()
função:
- Quando os usuários digitam um caractere, use a
setTimeout()
função para agendar a execução da função search() após um período de tempo. - Se os usuários continuarem digitando, cancele o cronômetro usando a
clearTimeout()
função. Caso o usuário pause ou pare de digitar, deixe o cronômetro executar a função agendada de busca.
O seguinte mostra a nova versão da search()
função:
let timeoutId;
const search = (searchTerm) => {
// reset the previous timer
if (timeoutId) {
clearTimeout(timeoutId);
}
// set up a new timer
timeoutId = setTimeout(async () => {
try {
const url = `https://en.wikipedia.org/w/api.php?action=query&list=search&prop=info|extracts&inprop=url&utf8=&format=json&origin=*&srlimit=10&srsearch=${searchTerm}`;
const response = await fetch(url);
const searchResults = await response.json();
// show the search result in the console
console.log({
'term': searchTerm,
'results': searchResults.query.search
});
} catch (error) {
console.log(error);
}
}, 500);
};
Linguagem de código: JavaScript ( javascript )
Como o await
código relacionado é movido para a função de retorno de chamada do setTimeout()
, você precisa marcar o retorno de chamada com a async
palavra-chave e remover a async
palavra-chave da search()
função.
Se você abrir o index.html
arquivo no navegador da web e digitar a palavra-chave debounce sem pausar (por meio segundo) e parar, verá que o aplicativo fará apenas uma solicitação de API.
E essa técnica é conhecida como debouncing .
O que é debouncing
Se você tiver uma tarefa demorada, como uma solicitação de API disparada com frequência, isso afetará o desempenho do aplicativo.
Debouncing é uma técnica de programação que limita o número de vezes que uma função é chamada.
Desenvolva uma função debounce reutilizável
A debounce()
função precisa aceitar uma função ( fn
), limitar o número de chamadas a ela e retornar uma função:
const debounce = (fn) => {
return (arg) => {
// logic to limit the number of call fn
fn(arg);
};
};
Linguagem de código: JavaScript ( javascript )
O seguinte usa as funções clearTimeout()
e setTimeout()
para eliminar a fn
função:
const debounce = (fn) => {
let timeoutId;
return (arg) => {
// cancel the previous timer
if (timeoutId) {
clearTimeout(timeoutId);
}
// setup a new timer
timeoutId = setTimeout(() => {
fn(arg);
}, 500);
};
};
Linguagem de código: JavaScript ( javascript )
Normalmente, a fn
função aceitará mais de um argumento. Para invocar a fn
função com uma lista de argumentos, você usa o apply()
método:
const debounce = (fn, delay=500) => {
let timeoutId;
return (...args) => {
// cancel the previous timer
if (timeoutId) {
clearTimeout(timeoutId);
}
// setup a new timer
timeoutId = setTimeout(() => {
fn.apply(null, args);
}, delay);
};
};
Linguagem de código: JavaScript ( javascript )
Como funciona:
- Primeiro, substitua o número codificado
500
pelodelay
argumento para que você possa especificar quanto tempo esperar antes de executar afn
função. O valor padrão do atraso é 500 ms. - Segundo, adicione the
...args
à função retornada. O...arg
é um parâmetro rest que permite coletar todos os argumentos dafn()
função em um arrayargs
. - Terceiro,
fn.apply(null, args)
executa afn()
função com os argumentos especificados noargs
array.
Use a função de rejeição
O seguinte remove a lógica de depuração da search()
função e usa a debounce()
função:
const search = debounce(async (searchTerm) => {
try {
const url = `https://en.wikipedia.org/w/api.php?action=query&list=search&prop=info|extracts&inprop=url&utf8=&format=json&origin=*&srlimit=10&srsearch=${searchTerm}`;
const response = await fetch(url);
const searchResults = await response.json();
// show the search result in the console
console.log({
'term': searchTerm,
'results': searchResults.query.search
});
} catch (error) {
console.log(error);
}
});
Linguagem de código: JavaScript ( javascript )
Converta os resultados da pesquisa em HTML
Mostraremos o título e o snippet de cada resultado da pesquisa na saída. Antes de fazer isso, precisaremos de algumas funções utilitárias:
Tira tags HTML
O title
e snippet
do resultado da pesquisa da chamada de API pode conter tags HTML. E é seguro remover todas as tags HTML antes de renderizá-las.
A seguinte função utilitária retira as tags HTML de uma string:
const stripHtml = (html) => {
let div = document.createElement('div');
div.textContent = html;
return div.textContent;
};
Linguagem de código: JavaScript ( javascript )
A stripHtml()
função aceita uma string HTML. Ele cria um <div>
elemento temporário, atribui innerHTML
a string HTML e retorna sua textContent
propriedade.
Observe que esta função só funcionará em navegadores da web porque depende da API DOM do navegador da web.
Destaque o termo de pesquisa
É mais intuitivo se os termos da pesquisa estiverem destacados no resultado da pesquisa.
Esta highlight()
função destaca todas as ocorrências de keyword
in str
, envolvendo cada ocorrência da palavra-chave em uma <span>
tag com a highlight
classe:
const highlight = (str, keyword, className = "highlight") => {
const hl = `<span class="${className}">${keyword}</span>`;
return str.replace(new RegExp(keyword, 'gi'), hl);
};
Linguagem de código: JavaScript ( javascript )
Observe que a função usa a expressão regular para substituir todas as ocorrências de keyword
pelo <span>
elemento.
Converta os resultados da pesquisa em HTML
A generateSearchResultHTML()
função a seguir converte os resultados da pesquisa em HTML:
const generateHTML= (results, searchTerm) => {
return results
.map(result => {
const title = highlight(stripHtml(result.title), searchTerm);
const snippet = highlight(stripHtml(result.snippet), searchTerm);
return `<article>
<a href="https://en.wikipedia.org/?curid=${result.pageid}">
<h2>${title}</h2>
</a>
<div class="summary">${snippet}...</div>
</article>`;
})
.join('');
}
Linguagem de código: JavaScript ( javascript )
Como funciona.
- Primeiro, use o
map()
método para retornar a representação HTML de cada resultado da pesquisa e ojoin()
método para unir os resultados da pesquisa (em formato HTML) em uma única string HTML. - Em segundo lugar, retire as tags HTML e destaque o termo de pesquisa
title
esnippet
retorne da chamada de API.
Mostrar os resultados da pesquisa
Altere o search()
método que usa a generateSearchResultHTML()
função e anexe seu resultado ao arquivo searchResultElem
. Além disso, redefina o resultado da pesquisa se o termo de pesquisa estiver vazio:
const search = debounce(async (searchTerm) => {
// if the search term is removed,
// reset the search result
if (!searchTerm) {
// reset the search result
searchResultElem.innerHTML = '';
return;
}
try {
// make an API request
const url = `https://en.wikipedia.org/w/api.php?action=query&list=search&prop=info|extracts&inprop=url&utf8=&format=json&origin=*&srlimit=10&srsearch=${searchTerm}`;
const response = await fetch(url);
const searchResults = await response.json();
// render search result
const searchResultHtml = generateSearchResultHTML(searchResults.query.search, searchTerm);
// add the search result to the searchResultElem
searchResultElem.innerHTML = searchResultHtml;
} catch (error) {
console.log(error);
}
});
Linguagem de código: JavaScript ( javascript )
Agora, se você abrir no index.html
navegador da web, verá o aplicativo funcionando.
Resumo
Neste tutorial, você aprendeu os seguintes pontos principais:
- Use a
fetch()
API para fazerGET
solicitações HTTP. - Use as
async/await
palavras-chave para deixar o código assíncrono mais limpo. - Compreenda a técnica de programação de debouncing e desenvolva uma
debounce()
função JavaScript reutilizável.