Como ReactiveX funciona?

ReactiveX

Sendo um desenvolvedor de software mobile, eu tenho que lidar com programação assíncrona diariamente. Para fornecer ao usuário a melhor experiência possível, tarefas como fazer uma requisição web, buscar informações no meu banco de dados, esperar algum processo secundário terminar ou baixar uma imagem devem ser executas de modo assíncrono. Mesmo com alguns anos de experiência, às vezes eu esqueço a sintaxe para alguma chamada assíncrona. Como eu tenho que implementar o callback para esse processo? Como eu devo lidar com o erro se alguma coisa der errado?. Existem centenas de formas de lidar com essas respostas, e, como desenvolvedor, é meu trabalho saber qual se encaixa melhor em cada situação. A primeira vez que eu li sobre ReactiveX, eu pensei comigo mesmo: “Ótimo, outra API assíncrona para memorizar…”. Eu não poderia estar mais enganado.

A API do ReactiveX (ou Rx) padroniza todos os processos assíncronos com uma sintaxe muito simples: onNext(), onError() e onCompletion(). É o fim da decoreba de sintaxes para lidar com aqueles callbacks que eu só escrevo duas vezes por ano. Sem mencionar que o código fica muito mais bonito já que boa parte de boilerplate é removido.

Ele se baseia em três ideias principais: o padrão Observador, o padrão Iterador e programação funcional. O padrão Observador é uma forma sensacional para lidar com tarefas assíncronas: o observable notifica todos seus receptores cada vez que um novo evento ocorre. O padrão Iterador permite um maior desacoplamento entre o tipo do objeto e os algoritmos, permitindo que ele seja usado em um grande número de cenários. Programação funcional não só torna o código mais conciso, mas também ajuda muito nesses cenários concorrentes. Essas ideias combinadas tornam ReactiveX uma ótima forma de lidar com programação assíncrona.

Ele é uma API muito direta, depois que você entende como observables, observers, operators e schedulers funcionam. Vamos respirar fundo e começar.

deep breath

Observables e observers

Essa parte é bem simples: observables vão emitir eventos, como eu mencionei antes, e alguns outros objetos (chamados de observers) vão se inscrever a esses observables e vão lidar com esses eventos emitidos.
Moleza, não é?

Operators

É aqui que grande parte da magia do Rx acontece.
Vamos supor que você quer reagir às mudanças em um campo de busca: pegar a entrada do usuário, criar uma requisição para seu backend e apresentar os resultados da busca para o usuário. Você sabe que não deve reagir para cada novo caractere que o usuário digitar, ou um usuário que digita rápido vai acabar causando muitas requisições em um curto período de tempo, o que seria mais difícil de lidar e adicionaria muita pressão sobre o backend. O que você faria nesse caso? Provavelmente criaria uma tarefa temporizada que iria checar se o campo de busca sofreu alguma mudança a cada poucos segundos, e se ele sofreu, enviar a requisição de busca. Isso acarreta mais código para lidar, e mais espaço para erros (temporizadores são uma grande fonte de problemas na minha experiência). E se eu te dissesse que ReactiveX pode lidar com tudo isso com apenas uma linha de código? Mágica, certo?
Estou falando sobre operators agora. A maioria desses caras opera sobre um observable e retorna outro observable, permitindo que você encadeie múltiplos deles para obter o comportamento desejado. No exemplo do campo de busca que eu mencionei antes, um único operator do tipo debounce teria atingido o comportamento que nós queríamos.

debounce

Existem operators que podem criar, transformar, filtrar, combinar observables e muito, muito mais. Você pode ter uma ideia boa de como usá-los aqui.

Schedulers

Esses caras me fazem querer usar Rx para todas as tarefas assíncronas que eu tenho.
Alguns operators especiais aceitam schedulers como um parâmetro para permitir multithreading na cadeia de operators. Isso permite que o Rx comece a lidar com um evento emitido por um observable em uma thread, processe parte dele em outra thread e apresente o resultado em uma terceira thread.

schedulers

Isso pode parecer com muitas threads para você. Mas a primeira vez que eu comecei uma requisição de rede em uma thread de entrada/saída, processei a resposta em uma thread secundária e atualizei a interface na thread principal com apenas três operadores a mais, eu vi o quão inestimáveis esses schedulers são.

Eu preciso usar ReactiveX ou eu vou morrer!

Você deve estar se perguntando se pode usar ReactiveX nos seus projetos e a resposta provavelmente é sim, porque ele foi implementado em diversas linguagens e plataformas. Confira a lista oficial de linguagens suportadas. Mas não se desespere se você não encontrar sua linguagem ou plataforma preferia ali, provavelmente você pode encontrar alguém no github que já implementou uma biblioteca para você.

Happy coding!

Sobre o autor.

Natan Grando
Natan Grando

Ama jogar videogame e desenvolver apps mobile. Sempre procurando por maneiras novas e melhores de resolver problemas.