você está escrevendo JavaScript e de repente perceber com horror e medo que você escreveu uma função enorme. Aconteceu ao melhor de nós. Agora vem o desejo quase imparável de separar a função em pedaços menores.
grandes funções significam muitas responsabilidades em um só lugar e, possivelmente, cheiro de código também, por isso é uma boa ideia em si. Mas você quer quebrar a função de tal forma que ela não perca seu significado ou contexto. Para fazer isso, você precisa pensar em encadeamento de método – também chamado de encadeamento de função. Este artigo explicará o que quero dizer com isso.
pré-Requisitos
Antes de começar, aqui estão algumas JavaScript conceitos que você já deve estar familiarizado com a:
- Seta funções
- Array métodos
- Assíncrona de funções
Mais experientes, os desenvolvedores têm alguma experiência com o Array
métodos, como o mapa, reduzir e filtro. Você provavelmente já se deparou com algo assim:
const food = ;// This type of usage is very commonfood .map(item => item.type) .reduce((result, fruit) => { result.push(fruit); return ; }, );// result:
o encadeamento de métodos acontece quando você deseja chamar várias funções usando o mesmo objeto e sua referência. No exemplo acima, o método array map
retorna um Array
, que tem um número formidável de métodos.
porque você retorna uma referência apontando para um Array
,você terá acesso a todas as propriedades de Array
. É o mesmo princípio que você usa para o seu próprio método encadeamento.
entender melhor isso
não vou cobrir todas as nuances de this
, mas é bom entender por que this
funciona da maneira que funciona. Não importa o quão experiente você seja, a palavra-chave isso pode ser difícil de entender. Muitas vezes é a razão pela qual as coisas não funcionam da maneira que você espera que eles 😅.
aqui está a essência disso: this
sempre apontará para a atual scope
ou instância de onde ela é chamada. Um exemplo:
const dog = { is: null, log: () => console.log(this.is), bark() { this.is = "woofing"; this.log(); return this; }, walk() { this.is = "walking"; this.log(); return this; }, eat() { this.is = "eating"; this.log(); return this; }};dog .bark() .eat() .walk();
quando você escreve uma função como esta( sem trocadilhos), você pode querer encadear métodos relacionados ao objeto. O objeto dog
tem 3 métodos: walk
, bark
e eat
. Toda vez que eu chamo qualquer uma de suas funções, um console deve mostrar a representação do que o cão está fazendo naquele momento exato.
mas há um problema com isso. Se você executá-lo no navegador, você vai perceber que não funciona como esperado. Isso ocorre porque as funções de seta usam escopo lexical, onde this
se refere ao seu escopo circundante – neste caso window
, não ao próprio objeto.
para resolver isso, devemos usar uma chamada de função anônima para representar a propriedade log
:
// instead of this: log: () => console.log(this.is),// use this: log() { console.log(this.is); }
agora, o escopo this
do cão estará acessível dentro da função.
Usando Classe
você pode obter o mesmo resultado usando classes:
class Dog { is = null; log() { console.log(this.is); } bark() { this.is = "woofing"; this.log(); return this; } walk() { this.is = "walking"; this.log(); return this; } eat() { this.is = "eating"; this.log(); return this; }}const dog = new Dog();dog .bark() .eat() .walk();
usando Prototype
se você tiver que usar prototype, faça assim:
function Dog() {}Dog.prototype.is = null;Dog.prototype.log = function() { console.log(this.is);};Dog.prototype.bark = function() { this.is = "woofing"; this.log(); return this;};Dog.prototype.walk = function() { this.is = "walking"; this.log(); return this;};Dog.prototype.eat = function() { this.is = "eating"; this.log(); return this;};const dog = new Dog();dog .bark() .eat() .walk();
E As Funções Assíncronas?
async
as funções são açúcar sintético para promessas e geradores. Quando você declara uma função async
, você sabe que ela retornará uma promessa. Por causa disso, você também terá acesso a todos os métodos da promessa.
const requests = { user: null, action: null, log(something) { console.log(this); }, async getUser() { this.user = await new Promise(resolve => { setTimeout(() => { resolve("Douglas Pires"); }, 1000); }); this.log("user"); return this; }, async registerAction() { this.action = await new Promise(resolve => { setTimeout(() => { resolve("programming stuff"); }, 1000); }); this.log("action"); return this; }};requests.getUser().then(() => requests.registerAction());
no entanto, não é uma boa ideia encadear um monte de promessas juntos. Eu recomendo usar um monte de await
palavras-chave em vez disso. É mais fácil e tornará seu código muito mais legível.
await requests.getUser(); // Douglas Piresawait requests.registerAction(); // programming
e você terá acesso às mesmas propriedades aqui:
console.log(requests.user); // Douglas Piresconsole.log(requests.action); // programming
em conclusão
funções de encadeamento vem a calhar quando você tem que manipular um objeto. Também é uma maneira prática de melhorar a legibilidade do seu código. No entanto, como você viu acima, você deve encadear com sabedoria.
neste artigo, falamos sobre this
, classes, protótipos e async
funções no contexto do encadeamento de métodos JavaScript. Espero que você tenha escolhido algumas dicas úteis e agora esteja mais bem informado sobre o assunto. Você pode encontrar meu repositório com todo o código no encadeamento do método JavaScript aqui. Vejo você no próximo post!
gostei de ler este artigo? Sinta-se à vontade para compartilhar nas redes sociais usando os botões abaixo. Alternativamente, também escrevi sobre como você pode construir um gerador de paleta de cores usando Nuxt e Vuetify. Vai ver!