RxJS: Primeiros passos e aprendizados de desenvolvimento

Por Higor Coimbra|
Atualizado: Jul 2023 |
Publicado: Ago 2021

Começando por uma definição da própria documentação, o RxJS é uma biblioteca para construção de programas assíncronos ou baseado em eventos, utilizando uma sequência de observables. Não entendeu nada? Vamos tentar separar então alguns pontos dessa frase: 

  • Programas assíncronos: o exemplo mais simples para esse tipo de programa é quando o seu método, função ou componente no front-end espera alguma resposta de uma API. Não há uma resposta imediata para a sua requisição, ou seja não há uma resposta síncrona mas sim assíncrona ao que você pediu o servidor da API. 
  • Programas baseados em eventos: se a sua aplicação tem o mínimo de interação com o usuário, provavelmente você tem alguma estrutura de eventos para saber quando o usuário clicou em determinada parte da tela ou quando ele digitou em algum campo, por exemplo. Cada uma dessas ações gera um evento, um alerta de que algo aconteceu. A partir do momento que você tem controle de quando essas ações são realizadas e trabalha no seu código em resposta a elas, você tem um programa baseado em eventos. 
  • Sequência de observables: Para entender o que é uma sequência de observables, precisamos entender primeiro o que é um observable. Por enquanto, entenda-se como um tipo muito importante para o RxJS, que processa eventos ou valores futuros. 

A documentação continua: o RxJS provê operadores, inspirados nos operadores de Array comuns a várias linguagens como map, filter, reduce, every, etc, que permitem lidar com assincronicidade e eventos como se fossem coleções

Apesar de ser mais utilizado no framework Angular, a biblioteca está no npm e pode ser utilizada em qualquer framework, inclusive substituindo bibliotecas de gerenciamento de estado como o redux

Por trás do RxJS, nós temos um padrão de projeto bem conhecido. Precisamos pegar carona em alguma das suas ideias para compreender o que foi pensado de estratégia para essa biblioteca. 

Padrão Observer em RxJS

Um padrão de projeto que pode ser utilizado para lidar com programas baseado em eventos é o Observer. Não à toa, o RxJS baseia a sua estrutura neste padrão. Primeiramente, define-se um objeto denominado Subject, que mantém uma lista de dependentes chamado observers, que são notificados a cada mudança de estado de alguma variável a qual se queira associar um evento. 

Para que fique claro, vejamos um diagrama desse padrão: 

Padrão Observer

No diagrama acima, a classe Subject possui uma propriedade com a coleção dos seus observers (observeCollection), um método para registrar novos observers (registerObserver) um método para desassociar observers do seu controle (unregisterObserver) e por fim, o método mais importante, de notificar os observers de alguma atualização (notifyObservers)

Uma interface Observer controla a assinatura do método de atualização em cada instância atrelada ao Subject. Por sua vez, cada observer concreto, possui um método de atualização a seu critério, contando que seja seguido a assinatura da interface. 

Basicamente, na maioria das vezes que se deseja enviar uma notificação de estado para algum lugar da sua aplicação, de maneira centralizada, podemos utilizar o padrão de projeto Observer. 

Quer ver mais conteúdos como esse?

Relação do padrão Observer 

Ok, mas qual é a relação desse padrão de projeto com o RxJS? Vejamos alguns conceitos essenciais dessa biblioteca, para que naturalmente nós enxerguemos a relação: 

  • Observable: coleção invocável de valores ou eventos futuros. 
  • Observer: coleção de callbacks que sabem como ler os valores entregues pelos Observables. 
  • Subscription (inscrição): representa a execução de um Observable, é primariamente utilizado para cancelar a sua execução. 

RxJS - Entre Chaves

Conseguimos associar diretamente o conceito de Observer do RxJS com o conceito de Observer do padrão de projeto descrito anteriormente, ambos estão sujeitos a receber valores emitidos por uma entidade, no caso do padrão de projeto, o Subject e no caso do RxJS os Observables com a realização da sua inscrição. 

Agora vamos aplicar esses conceitos na prática, com alguns exemplos trazidos da própria documentação da biblioteca. 

Exemplo prático da aplicação do padrão na biblioteca 

Exemplo 1: 

[js]

import { of } from ‘rxjs’;

of(10, 20, 30)
.subscribe(
next => console.log(‘next:’, next),
err => console.log(‘error:’, err),
() => console.log(‘the end’),
);

// Saídas
// next: 10
// next: 20
// next: 30
// Fim

[/js]

Para que possamos explicar qualquer exemplo de RxJS, nós precisamos de alguma fonte de valores ou eventos futuros, um Observable. Para esse exemplo, foi utilizado o operador of, que recebe uma lista de argumentos e retorna um Observable que emitirá cada valor de forma sequencial e completará. 

Levando em consideração a saída que esse código emitiu, nós percebemos que cada valor emitido pelo operador of (10, 20 e 30), foi passado para dentro da callback logo abaixo do método subscribe. Mais especificamente, cada valor foi passado somente pela callback com o argumento next

Considerando esse resultado, vamos quebrar esse código em algumas partes para que possamos entender o que está acontecendo: 

import { of } from 'rxjs';
of(10, 20, 30) 

Primeiramente, importamos o operador of do pacote rxjs. Em seguida chamamos a função passando três argumentos que serão emitidos em sequência, como explicado anteriormente. 

.subscribe(

O método subscribe irá gerar uma Subscription ou seja, é por meio desse método que permitimos a execução da emissão de valores do Observable definido anteriormente. Dentro do subscribe podemos passar 3 argumentos:

next => console.log('next:', next),
err => console.log('error:', err),
() => console.log('the end'),

  • O primeiro argumento é uma callback de next, ou seja, essa função irá tratar cada valor emitido pelo Observable, nesse caso, para o operador of, ela será executada para os valores, 10, 20 e 30 (emitidos anteriormente), respectivamente.
  • O segundo argumento é uma callback de err, ou seja, essa função será executada caso durante a emissão dos valores do Observable haja algum sinal de erro emitido pelo mesmo.
  • O terceiro e último argumento é uma callback de complete. Os Observables podem emitir um sinal de complete, indicando que todos os seus valores ou eventos futuros foram emitidos e a partir de agora nada mais será emitido. No caso do of, esse sinal é emitido junto com a emissão do último valor, no caso do nosso exemplo, o operador emite o valor 30 e o sinal de complete. A callback de complete realiza alguma ação assim que o Observable emite este tipo de sinal.

Ponto de apoio: Marble Diagram 

Podemos representar o código do exemplo e a sua execução através de um diagrama chamado marble diagram, ou diagrama de bolinhas: 

RxJS

Esse diagrama é dividido nas seguintes partes: 

  • O quadrado representa a execução de um operador, com os seus argumentos.
  • A seta representa uma passagem de tempo. 
  • As bolinhas são os valores emitidos ao longo do tempo. 
  • O traço vertical representa o ponto onde o Observable emitiu o sinal de complete. 

Então, assim como vimos, juntamente com o valor 30 emitido pelo operador, ele emite também o sinal de complete, como visto na última bolinha do diagrama. 

Conclusão 

Dada o nosso exemplo, o mais interessante é pensar que se substituíssemos o operador of por algum Observable que, por exemplo, emitisse cada valor digitado pelo usuário num campo de formulário, poderíamos fazer uma tratativa na função next de limitação de caracteres desse campo, ou uma busca no lado do servidor do termo pesquisado, dentre outras aplicações. Esse é um exemplo do poder do RxJS e seu paradigma reativo. 

Neste artigo conseguimos associar um conceito da Engenharia de Software, o padrão Observer, que permitiu a criação do RxJS. Também abordamos algumas peças fundamentais para que você entenda exemplos mais complexos daqui para frente, como a divisão dos argumentos da função subscribe. Dessa maneira você conseguirá ir agregando outras peças a esse entendimento e utilizar melhor esta biblioteca poderosa nos seus projetos. 

Gostou do conteúdo? Em nosso podcast técnico, o Entre Chaves, você confere insights como esse para sua carreira de desenvolvedor(a) ou entusiasta do assunto. Te esperamos lá!

RxJS - Entre Chaves

Quer saber mais?