of() - Emissão Sequencial de Valores
of() é a Creation Function mais simples que emite os valores especificados um a um em sequência.
Visão Geral
of() emite os valores passados como argumentos em sequência conforme são subscritos, e completa imediatamente após todos os valores serem emitidos. É frequentemente usada para criar código de teste ou dados mock.
Assinatura:
function of<T>(...args: T[]): Observable<T>Documentação Oficial: 📘 RxJS Official: of()
Uso Básico
of() permite que múltiplos valores sejam passados separados por vírgula.
import { of } from 'rxjs';
const values$ = of(1, 2, 3, 4, 5);
values$.subscribe({
next: value => console.log('Valor:', value),
error: err => console.error('Erro:', err),
complete: () => console.log('Completo')
});
// Saída:
// Valor: 1
// Valor: 2
// Valor: 3
// Valor: 4
// Valor: 5
// CompletoCaracterísticas Importantes
1. Emissão Síncrona
of() emite todos os valores sincronamente na assinatura.
import { of } from 'rxjs';
console.log('Antes da assinatura');
of('A', 'B', 'C').subscribe(value => console.log('Valor:', value));
console.log('Depois da assinatura');
// Saída:
// Antes da assinatura
// Valor: A
// Valor: B
// Valor: C
// Depois da assinatura2. Conclusão Imediata
Notifica complete imediatamente após emitir todos os valores.
import { of } from 'rxjs';
of(1, 2, 3).subscribe({
next: val => console.log(val),
complete: () => console.log('Completo!')
});
// Saída: 1, 2, 3, Completo!3. Pode Emitir Qualquer Tipo de Valor
Valores de qualquer tipo podem ser emitidos, de tipos primitivos a objetos e arrays.
import { of } from 'rxjs';
// Tipos primitivos
of(42, 'olá', true).subscribe(console.log);
// Objetos
of(
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
).subscribe(console.log);
// Arrays (emite o array em si como um valor único)
of([1, 2, 3], [4, 5, 6]).subscribe(console.log);
// Saída: [1, 2, 3], [4, 5, 6]4. Observable Cold
of() é um Observable Cold. Cada assinatura inicia uma execução independente.
import { of } from 'rxjs';
const values$ = of(1, 2, 3);
// Primeira assinatura
values$.subscribe(val => console.log('Assinante A:', val));
// Segunda assinatura (executada independentemente)
values$.subscribe(val => console.log('Assinante B:', val));
// Saída:
// Assinante A: 1
// Assinante A: 2
// Assinante A: 3
// Assinante B: 1
// Assinante B: 2
// Assinante B: 3NOTE
Características do Observable Cold:
- Execução independente é iniciada para cada assinatura
- Cada assinante recebe seu próprio fluxo de dados
- Se você precisa compartilhar dados, precisa torná-lo Hot com
share()etc.
Veja Observable Cold e Observable Hot para mais informações.
Diferença Entre of() e from()
of() e from() têm comportamento diferente ao lidar com arrays. Este é um ponto comum de confusão.
import { of, from } from 'rxjs';
// of() - emite o array como um valor único
of([1, 2, 3]).subscribe(console.log);
// Saída: [1, 2, 3]
// from() - emite cada elemento do array individualmente
from([1, 2, 3]).subscribe(console.log);
// Saída: 1, 2, 3IMPORTANT
Critérios de Uso:
- Para emitir o array em si →
of([1, 2, 3]) - Para emitir cada elemento de um array separadamente →
from([1, 2, 3])
Casos de Uso Prático
1. Criação de Dados de Teste e Mock
of() é mais frequentemente usada para criar dados mock em código de teste.
import { of } from 'rxjs';
// Dados mock de usuário
function getMockUser$() {
return of({
id: 1,
name: 'Usuário de Teste',
email: 'teste@exemplo.com'
});
}
// Usar em testes
getMockUser$().subscribe(user => {
console.log('Usuário:', user.name); // Usuário: Usuário de Teste
});2. Fornecendo Valores Padrão
Usado para fornecer valores de fallback em caso de erros ou valores padrão.
import { of, throwError } from 'rxjs';
import { catchError } from 'rxjs';
function fetchData(id: number) {
if (id < 0) {
return throwError(() => new Error('ID inválido'));
}
return of({ id, data: 'alguns dados' });
}
fetchData(-1).pipe(
catchError(err => {
console.error('Erro:', err.message);
return of({ id: 0, data: 'dados padrão' }); // Valor padrão
})
).subscribe(result => console.log(result));
// Saída: Erro: ID inválido
// { id: 0, data: 'dados padrão' }3. Emitir Múltiplos Valores Gradualmente
Usado para executar múltiplas etapas em sequência.
import { of } from 'rxjs';
import { concatMap, delay } from 'rxjs';
of('Carregando...', 'Processando...', 'Pronto!').pipe(
concatMap(message => of(message).pipe(delay(1000)))
).subscribe(console.log);
// Saída (a cada 1 segundo):
// Carregando...
// Processando...
// Pronto!4. Retornar Valores em Ramificação Condicional
Usado em combinação com iif() e switchMap() para retornar valores de acordo com condições.
import { of, iif } from 'rxjs';
const isAuthenticated = true;
iif(
() => isAuthenticated,
of('Bem-vindo de volta!'),
of('Por favor, faça login')
).subscribe(console.log);
// Saída: Bem-vindo de volta!Usando em Pipeline
of() é usado como ponto de partida de um pipeline ou para injetar dados ao longo do caminho.
import { of } from 'rxjs';
import { map, filter } from 'rxjs';
of(1, 2, 3, 4, 5).pipe(
filter(n => n % 2 === 0), // Apenas números pares
map(n => n * 10) // Multiplicar por 10
).subscribe(console.log);
// Saída: 20, 40Erros Comuns
1. Passando um Array Diretamente
// ❌ Errado - todo o array é emitido como um valor único
of([1, 2, 3]).subscribe(console.log);
// Saída: [1, 2, 3]
// ✅ Correto - use from() para emitir cada elemento separadamente
from([1, 2, 3]).subscribe(console.log);
// Saída: 1, 2, 3
// ✅ Ou use sintaxe de spread
of(...[1, 2, 3]).subscribe(console.log);
// Saída: 1, 2, 32. Confusão com Processamento Assíncrono
Note que of() emite sincronamente. Não é processamento assíncrono.
// ❌ Isso não se torna assíncrono
of(fetchDataFromAPI()).subscribe(console.log);
// fetchDataFromAPI() executa imediatamente e o objeto Promise é emitido
// ✅ Use from() para fazer stream de uma Promise
from(fetchDataFromAPI()).subscribe(console.log);Considerações de Desempenho
of() é muito leve e tem pouco overhead de desempenho. No entanto, ao emitir grande número de valores, lembre-se do seguinte.
TIP
Ao emitir um grande número de valores (milhares ou mais) sequencialmente, considere usar from() ou range().
Funções de Criação Relacionadas
| Função | Diferença | Uso |
|---|---|---|
| from() | Converter de array ou Promise | Fazer stream de iterables ou Promises |
| range() | Gerar um intervalo de números | Emitir números consecutivos |
| EMPTY | Completar imediatamente sem emitir nada | Quando um stream vazio é necessário |
Resumo
of()é a Creation Function mais simples que emite os valores especificados em sequência- Emitida sincronamente na assinatura e completa instantaneamente
- Ideal para dados de teste e criação de mock
- Se um array é passado, o array em si é emitido (diferente de
from()) - Use
from()para processamento assíncrono