Conversão de filtros RxJS para Async/Await
Source: Dev.to
Comparando Fluxo Reativo e Assíncrono: Transformações Equivalentes
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. O programa continua a executar outras tarefas e, posteriormente, é notificado quando a operação assíncrona termina. Isso geralmente é alcançado por meio de callbacks, Promises ou async/await. É ideal 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 é 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 é a capacidade de lidar com dados que chegam de forma contínua e em volumes variados, tornando-o ideal para sistemas de tempo real e 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
Chamada Assíncrona Única (Promise) e Fluxo Reativo
Assíncrono (JavaScript com Promises):
async function fetchData() {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
console.log(data);
}
fetchData();
Reativo (RxJS):
import { fromFetch } from 'rxjs/fetch';
import { switchMap, tap, of } from 'rxjs';
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();
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.
Mapeamento (Map) e Processamento de Dados
Assíncrono (JavaScript com Promise.all):
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();
Reativo (RxJS):
import { forkJoin, fromFetch } from 'rxjs';
import { switchMap, 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));
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.
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 aproveitar ao máximo seus pontos fortes e criar aplicações robustas e eficientes. A combinação dessas técnicas, muitas vezes, é a chave para o sucesso em sistemas complexos.