DEV Community

Cover image for RxJS Subjects em Angular
Levy Henrique Alves Nunes
Levy Henrique Alves Nunes

Posted on

RxJS Subjects em Angular

Os Subjects são uma parte crucial da biblioteca RxJS e são frequentemente usados em aplicações Angular para gerenciar e manipular fluxos de dados reativos. Vamos mergulhar nas diferenças entre os diferentes tipos de Subjects e ver exemplos práticos de como eles são aplicados em aplicações Angular.

Diferenças entre Subject, BehaviorSubject, ReplaySubject e AsyncSubject

1. Subject

  • Definição: Um Subject é tanto um Observable quanto um Observer. Isso significa que você pode tanto emitir valores para ele quanto se inscrever nele.
  • Características: Ao se inscrever em um Subject depois que ele emitiu valores, você não receberá os valores anteriores. Você só receberá os valores emitidos após a inscrição.

2. BehaviorSubject

  • Definição: Um BehaviorSubject é semelhante a um Subject, mas armazena o último valor emitido. Assim, cada novo inscrito receberá imediatamente o último valor emitido antes da sua inscrição.
  • Características: Ao criar um BehaviorSubject, você precisa fornecer um valor inicial. Esse será o valor que os novos inscritos receberão se não houver outro valor emitido.

3. ReplaySubject

  • Definição: Um ReplaySubject grava os valores emitidos e pode reemitir esses valores para novos inscritos.
  • Características: Ao criar um ReplaySubject, você pode especificar quantos valores recentes deseja armazenar e reemitir para novos inscritos.

4. AsyncSubject

  • Definição: Um AsyncSubject é semelhante ao BehaviorSubject no sentido de que armazena o último valor. No entanto, o AsyncSubject só emite o valor no momento da conclusão.
  • Características: Se você se inscrever em um AsyncSubject e ele já tiver sido concluído, receberá imediatamente o último valor emitido.

Exemplos Práticos em Aplicações Angular

1. Subject

Imagine um serviço que informa quando um usuário foi atualizado:

import { Subject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class UserService {
  userUpdated = new Subject<void>();

  updateUser() {
    // Lógica de atualização do usuário
    this.userUpdated.next();
  }
}
Enter fullscreen mode Exit fullscreen mode

Em um componente:

@Component({
  // ...
})
export class UserComponent implements OnInit {
  constructor(private userService: UserService) {}

  ngOnInit() {
    this.userService.userUpdated.subscribe(() => {
      console.log('Usuário atualizado!');
    });
  }
}
Enter fullscreen mode Exit fullscreen mode

2. BehaviorSubject

Utilizado para armazenar o estado atual do usuário:

import { BehaviorSubject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class UserService {
  private currentUser = new BehaviorSubject<User>({ name: 'Guest' });

  getCurrentUser() {
    return this.currentUser.asObservable();
  }

  updateCurrentUser(newUser: User) {
    this.currentUser.next(newUser);
  }
}
Enter fullscreen mode Exit fullscreen mode

3. ReplaySubject

Perfeito para armazenar um histórico de mensagens em um chat:

import { ReplaySubject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class ChatService {
  private messages = new ReplaySubject<string>(5); // Armazena as últimas 5 mensagens

  getMessages() {
    return this.messages.asObservable();
  }

  addMessage(message: string) {
    this.messages.next(message);
  }
}
Enter fullscreen mode Exit fullscreen mode

4. AsyncSubject

Útil para ações que só nos interessam no final, como um pedido HTTP:

import { AsyncSubject } from 'rxjs';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class DataService {
  private dataSubject = new AsyncSubject<Data>();

  constructor(private http: HttpClient) {}

  fetchData() {
    this.http.get<Data>('url').subscribe(data => {
      this.dataSubject.next(data);
      this.dataSubject.complete();
    });

    return this.dataSubject.asObservable();
  }
}
Enter fullscreen mode Exit fullscreen mode

Ao usar o AsyncSubject neste exemplo, os inscritos só receberão um valor quando o pedido HTTP for concluído.

Conclusão

Os Subjects e suas variantes oferecem uma flexibilidade incrível ao trabalhar com fluxos de dados reativos em Angular. Escolher o tipo correto de Subject pode simplificar seu código e tornar sua aplicação mais eficiente.

Top comments (0)