Tenho procurado entender esses 3:
Assunto , assunto de comportamento e assunto de repetição . Eu gostaria de usá-los e saber quando e por que, quais são os benefícios de usá-los e embora tenha lido a documentação, assistido tutoriais e pesquisado no google, não consegui entender isso.
Então, qual é o seu propósito? Um caso do mundo real seria muito apreciado, pois não é necessário nem codificar.
Eu preferiria uma explicação clara, não apenas "a + b => c você está inscrito ..."
Obrigado
javascript
angular
rxjs
reactive-programming
angular2-observables
Paul Samsotha
fonte
fonte
Respostas:
Na verdade, tudo se resume a comportamento e semântica. Com um
Subject
- um assinante só obterá valores publicados que foram emitidos após a assinatura. Pergunte a si mesmo: é isso que você quer? O assinante precisa saber alguma coisa sobre os valores anteriores? Se não, você pode usar este, caso contrário, escolha um dos outros. Por exemplo, com comunicação componente a componente. Digamos que você tenha um componente que publica eventos para outros componentes em um clique de botão. Você pode usar um serviço com assunto para se comunicar.BehaviorSubject
- o último valor é armazenado em cache. Um assinante receberá o valor mais recente na assinatura inicial. A semântica desse assunto é representar um valor que muda com o tempo. Por exemplo, um usuário conectado. O usuário inicial pode ser um usuário anônimo. Mas, uma vez que um usuário efetua login, o novo valor é o estado do usuário autenticado.O
BehaviorSubject
é inicializado com um valor inicial. Isso às vezes é importante para a preferência de codificação. Digamos, por exemplo, que você o inicialize com umnull
. Em seguida, em sua assinatura, você precisa fazer uma verificação nula. Talvez OK, ou talvez irritante.ReplaySubject
- pode armazenar em cache até um determinado número de emissões. Todos os assinantes obterão todos os valores em cache na assinatura. Quando você precisaria desse comportamento? Sinceramente, não tive necessidade de tal comportamento, exceto no seguinte caso:Se você inicializar a
ReplaySubject
com um tamanho de buffer de1
, na verdade ele se comportará como umBehaviorSubject
. O último valor é sempre armazenado em cache, por isso age como um valor que muda com o tempo. Com isso, não há necessidade de umanull
verificação como no caso doBehaviorSubject
inicializado com anull
. Nesse caso, nenhum valor é emitido ao assinante até a primeira publicação.Portanto, tudo se resume ao comportamento que você está esperando (quanto a qual usar). Na maioria das vezes, você provavelmente desejará usar um
BehaviorSubject
porque o que realmente deseja representar é a semântica do "valor ao longo do tempo". Mas eu pessoalmente não vejo nada de errado com a substituição deReplaySubject
inicializado com1
.O que você quer evitar é usar o vanilla
Subject
quando o que você realmente precisa é algum comportamento de cache. Por exemplo, você está escrevendo um guarda de roteamento ou uma resolução. Você busca alguns dados naquele guarda e os coloca em um serviçoSubject
. Então no componente roteado você assina o serviço sujeito para tentar pegar aquele valor que foi emitido na guarda. OOPs. Onde está o valor? Já foi emitido, DUH. Use um assunto de "cache"!Veja também:
fonte
ReplaySubject
com um tamanho de buffer de 1 era exatamente o que eu precisava. Eu tinha um guarda de rota que precisava do valor, mas precisava aguardar a primeira emissão. Então, aBehaviorSubject
não estava cortando, porque eu não queria um valor inicial (null
também não funcionaria porque eu estava usando para significar um estado)resolve
classe de guarda Angular . Meu serviço de dados pode ser assíncrono ou síncrono (se os dados já tiverem sido recuperados). Se fosse síncrono, o Subject.next () estava sendo disparado antes de aresolve
função retornar e ser assinada pelo Angular internamente. BehaviourSubject possivelmente funcionaria, mas eu teria que chamar explicitamentecomplete()
e também adicionarnull
verificações para o valor inicial. O que funcionou era novoReplaySubject<DataType>(1)
eresolveSubject.asObservable().take(1).map(....)
.asObservable()
o Observable, envio um valor denull
para assinantes antes mesmo de chamarnext()
meu ReplaySubject. Achei que não deveria ter um valor inicial diferente de BehaviorSubject?Um resumo prático dos diferentes tipos observáveis, nomenclatura não intuitiva, eu sei lol .
Subject
- Um assinante só obterá valores publicados nele - após a assinatura ser feita.BehaviorSubject
- Novos assinantes obtêm o último valor publicado OU valor inicial imediatamente após a assinatura.ReplaySubject
- Novos assinantes recebem todos os valores publicados anteriormente imediatamente após a assinaturafonte
Com este exemplo, aqui está o resultado que será impresso no console:
Aqui está um exemplo de uso para temas de repetição em que
buffer of 2 previous values
são mantidos e emitidos em novas assinaturas:Aqui está o que isso nos dá no console:
E o resultado:
Referência: https://alligator.io/rxjs/subjects/
fonte
De: Randall Koutnik livro “Build Reactive Websites with RxJS.” :
Um assunto é um objeto que é um observável turboalimentado. Em sua essência, um Assunto atua como um observável regular, mas cada assinatura está ligada à mesma fonte. Os sujeitos também são observadores e possuem métodos next, error e done para enviar dados a todos os assinantes de uma vez. Como os sujeitos são observadores, eles podem ser passados diretamente para uma chamada de inscrição, e todos os eventos do observável original serão enviados por meio do sujeito para seus assinantes.
Podemos usar o ReplaySubject para rastrear o histórico. Um ReplaySubject registra os últimos n eventos e os envia de volta para cada novo assinante. Por exemplo, no aplicativo de bate-papo. Podemos usá-lo para rastrear o registro do histórico de bate-papo anterior.
Um BehaviorSubject é uma versão simplificada do ReplaySubject . O ReplaySubject armazenou um número arbitrário de eventos, o BehaviorSubject registra apenas o valor do evento mais recente. Sempre que um BehaviorSubject registra uma nova assinatura, ele emite o valor mais recente para o assinante, bem como quaisquer novos valores que são transmitidos. O BehaviorSubject é útil ao lidar com unidades únicas de estado, como opções de configuração.
fonte
A resposta mais votada está claramente errada, alegando que:
"Se você inicializar um
ReplaySubject
com um tamanho de buffer de 1, ele realmente se comportará como umBehaviorSubject
"Isso não é totalmente verdade; verifique esta ótima postagem no blog sobre as diferenças entre os dois. Por exemplo, se você assinar um concluído
BehaviorSubject
, você não receberá o último valor, mas para umReplaySubject(1)
você receberá o último valor.Esta é uma diferença importante que não deve ser esquecida:
Verifique este exemplo de código aqui, que vem de outra excelente postagem de blog sobre o assunto.
fonte
fonte