DEV Community

Lucas Pereira de Souza
Lucas Pereira de Souza

Posted on

Conversão de filtros RxJS para Async/Await

logotech

## Comparando Fluxo Reativo e Assíncrono: Transformações Equivalentes

No desenvolvimento de software moderno, a necessidade de lidar com operações de longa duração e eventos de forma eficiente é crucial. Duas abordagens populares para alcançar isso são a programação assíncrona e o fluxo reativo. Embora ambas compartilhem o objetivo de melhorar a capacidade de resposta e a escalabilidade, elas se diferenciam em seus princípios e implementações. Este artigo explora as nuances dessas abordagens, comparando-as e demonstrando transformações equivalentes para uma melhor compreensão.

Programação Assíncrona: O Básico

A programação assíncrona permite que um programa inicie uma operação sem esperar que ela seja concluída imediatamente. Em vez disso, o programa continua a executar outras tarefas e, posteriormente, é notificado quando a operação assíncrona é finalizada. Isso geralmente é alcançado por meio de callbacks, Promises ou async/await. A programação assíncrona é excelente para lidar com operações de I/O (entrada/saída), como requisições de rede ou leitura de arquivos, onde o tempo de espera pode ser significativo.

Fluxo Reativo: Reagindo a Dados

O fluxo reativo, por outro lado, é uma abordagem mais orientada a dados. Ele se concentra em como os dados são emitidos, recebidos e transformados ao longo do tempo. Um fluxo reativo é essencialmente uma sequência de eventos que podem ser observados e reagidos. Frameworks como RxJava, RxJS e Reactor fornecem ferramentas para criar, combinar e transformar fluxos de dados de maneira declarativa. A principal vantagem do fluxo reativo é sua capacidade de lidar com dados que chegam de forma contínua e em volumes variados, tornando-o ideal para sistemas de tempo real e processamento de dados em streaming.

Comparando as Abordagens

Característica Programação Assíncrona Fluxo Reativo
Foco Execução não bloqueante de operações. Fluxos de dados e reatividade.
Modelo de Dados Geralmente trabalha com dados únicos ou resultados. Opera em fluxos (sequências) de dados.
Notificação Callbacks, Promises, async/await. Observadores (Observers) e Assinaturas (Subscriptions).
Complexidade Menos complexo para operações simples. Pode ser mais complexo para entender no início.
Casos de Uso I/O, tarefas em segundo plano. Sistemas de tempo real, streaming de dados.
Principal Vantagem Melhoria na capacidade de resposta. Flexibilidade no tratamento de fluxos de dados.

Transformações Equivalentes: Assíncrono vs. Reativo

Apesar de suas diferenças, é possível encontrar equivalências entre as operações assíncronas e as transformações em fluxos reativos. Vamos considerar alguns exemplos:

  1. Chamada Assíncrona Única (Promise) e Fluxo Reativo:
*   **Assíncrono (JavaScript com Promises):**
Enter fullscreen mode Exit fullscreen mode
    ```javascript
    async function fetchData() {
      const response = await fetch('https://api.example.com/data');
      const data = await response.json();
      console.log(data);
    }
    fetchData();
    ```
Enter fullscreen mode Exit fullscreen mode
*   **Reativo (RxJS):**
Enter fullscreen mode Exit fullscreen mode
    ```javascript
    import { fromFetch } from 'rxjs/operators';
    import { map, tap } from 'rxjs/operators';

    fromFetch('https://api.example.com/data')
      .pipe(
        switchMap(response => {
          if (response.ok) {
            return response.json();
          } else {
            return of({ error: response.status });
          }
        }),
        tap(data => console.log(data))
      )
      .subscribe();
    ```
Enter fullscreen mode Exit fullscreen mode
Neste exemplo, a chamada assíncrona `fetch` é equivalente a um fluxo reativo que emite um único valor após a conclusão da requisição.
Enter fullscreen mode Exit fullscreen mode
  1. Mapeamento (Map) e Processamento de Dados:
*   **Assíncrono (JavaScript com `Promise.all`):**
Enter fullscreen mode Exit fullscreen mode
    ```javascript
    async function processData() {
      const results = await Promise.all([
        fetch('https://api.example.com/data1').then(res => res.json()),
        fetch('https://api.example.com/data2').then(res => res.json())
      ]);
      const mappedResults = results.map(item => item.value * 2);
      console.log(mappedResults);
    }
    processData();
    ```
Enter fullscreen mode Exit fullscreen mode
*   **Reativo (RxJS):**
Enter fullscreen mode Exit fullscreen mode
    ```javascript
    import { forkJoin } from 'rxjs';
    import { map } from 'rxjs/operators';

    forkJoin({
      data1: fromFetch('https://api.example.com/data1').pipe(switchMap(response => response.json())),
      data2: fromFetch('https://api.example.com/data2').pipe(switchMap(response => response.json()))
    })
    .pipe(
      map(results => [results.data1.value * 2, results.data2.value * 2])
    )
    .subscribe(mappedResults => console.log(mappedResults));
    ```
Enter fullscreen mode Exit fullscreen mode
Ambos os exemplos demonstram como transformar dados recebidos. No assíncrono, usa-se `Promise.all` e `map`; no reativo, `forkJoin` (para combinar fluxos) e `map`.
Enter fullscreen mode Exit fullscreen mode

Conclusão

Tanto a programação assíncrona quanto o fluxo reativo são ferramentas poderosas para construir aplicações modernas. A escolha entre elas depende dos requisitos específicos do projeto. A programação assíncrona é adequada para tarefas simples e onde a capacidade de resposta é crucial. O fluxo reativo brilha em cenários que envolvem fluxos contínuos de dados e transformações complexas. Entender as equivalências entre essas abordagens permite que você aproveite ao máximo seus pontos fortes e crie aplicações robustas e eficientes. A combinação dessas técnicas, muitas vezes, é a chave para o sucesso em sistemas complexos.

Top comments (0)