RxJS - Guia Rápido
Este capítulo trata de informações sobre recursos, vantagens e desvantagens do RxJS. Aqui, também aprenderemos quando usar o RxJS.
A forma completa de RxJS é Reactive Extension for Javascript. É uma biblioteca javascript que usa observáveis para trabalhar com programação reativa que lida com chamadas de dados assíncronas, retornos de chamada e programas baseados em eventos. O RxJS pode ser usado com outras bibliotecas e estruturas Javascript. É suportado por javascript e também com typescript.
O que é RxJS?
De acordo com o site oficial da RxJS , é definida como uma biblioteca para composição de programas assíncronos e baseados em eventos usando sequências observáveis. Ele fornece um tipo de núcleo, o Observable, tipos de satélite (Observer, Schedulers, Assuntos) e operadores inspirados por Array # extras (map, filter, reduce, every, etc.) para permitir o tratamento de eventos assíncronos como coleções.
Características do RxJS
No RxJS, os seguintes conceitos cuidam de lidar com a tarefa assíncrona -
Observável
Um observável é uma função que cria um observador e o anexa à fonte onde os valores são esperados, por exemplo, cliques, eventos de mouse de um elemento dom ou uma solicitação Http, etc.
Observador
É um objeto com os métodos next (), error () e complete (), que será chamado quando houver interação com o observável, isto é, a fonte interage para um exemplo de clique de botão, solicitação Http, etc.
Inscrição
Quando o observável é criado, para executar o observável, precisamos assiná-lo. Também pode ser usado para cancelar a execução.
Operadores
Um operador é uma função pura que recebe observáveis como entrada e a saída também é observável.
Sujeito
Um assunto é um observável que pode transmitir, ou seja, falar com muitos observadores. Considere um botão com um ouvinte de evento, a função anexada ao evento usando addlistener é chamada toda vez que o usuário clica no botão uma funcionalidade semelhante também vai para o assunto.
Schedulers
Um planejador controla a execução de quando a assinatura deve ser iniciada e notificada.
Quando usar o RxJS?
Se o seu projeto consiste em muitas tarefas de manipulação assíncrona, o RxJS é uma boa escolha. Ele é carregado por padrão com o projeto Angular.
Vantagens de usar RxJS
A seguir estão as vantagens de usar RxJS -
O RxJS pode ser usado com outras bibliotecas e estruturas Javascript. É suportado por javascript e também com typescript. Poucos exemplos são Angular, ReactJS, Vuejs, nodejs etc.
RxJS é uma biblioteca incrível quando se trata de manipulação de tarefas assíncronas. RxJS usa observáveis para trabalhar com programação reativa que lida com chamadas de dados assíncronas, callbacks e programas baseados em eventos.
O RxJS oferece uma enorme coleção de operadores em categorias matemáticas, de transformação, de filtragem, de utilidade, condicionais, de tratamento de erros e de junção que tornam a vida mais fácil quando usados com programação reativa.
Desvantagens de usar RxJS
A seguir estão as desvantagens de usar RxJS -
Depurar o código com observáveis é um pouco difícil.
À medida que você começa a usar os Observáveis, pode terminar seu código completo dentro dos observáveis.
Neste capítulo, vamos instalar o RxJS. Para trabalhar com RxJS, precisamos da seguinte configuração -
- NodeJS
- Npm
- Instalação do pacote RxJS
Instalação NODEJS e NPM
É muito fácil instalar o RxJS usando o npm. Você precisa ter nodejs e npm instalados em seu sistema. Para verificar se NodeJS e npm estão instalados em seu sistema, tente executar o seguinte comando em seu prompt de comando.
E:\>node -v && npm -v
v10.15.1
6.4.1
Caso você esteja obtendo a versão, significa que nodejs e npm estão instalados em seu sistema e a versão é 10 e 6 agora no sistema.
Se não imprimir nada, instale nodejs em seu sistema. Para instalar o nodejs, vá para a página inicialhttps://nodejs.org/en/download/ de nodejs e instale o pacote com base em seu sistema operacional.
A página de download do nodejs será semelhante à seguinte -
Com base no seu sistema operacional, instale o pacote necessário. Assim que o nodejs for instalado, o npm também será instalado junto com ele. Para verificar se o npm está instalado ou não, digite npm –v no terminal. Ele deve exibir a versão do npm.
Instalação do pacote RxJS
Para iniciar a instalação do RxJS, primeiro crie uma pasta chamada rxjsproj/ onde praticaremos todos os exemplos RxJS.
Uma vez que a pasta rxjsproj/ é criado, execute o comando npm init, para a configuração do projeto conforme mostrado abaixo
E:\>mkdir rxjsproj
E:\>cd rxjsproj
E:\rxjsproj>npm init
Npm initcomando fará algumas perguntas durante a execução, apenas pressione enter e prossiga. Assim que a execução do npm init estiver concluída, ele criarápackage.json dentro de rxjsproj / como mostrado abaixo -
rxjsproj/
package.json
Agora você pode instalar o rxjs usando o comando abaixo -
npm install ---save-dev rxjs
E:\rxjsproj>npm install --save-dev rxjs
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN [email protected] No description
npm WARN [email protected] No repository field.
+ [email protected]
added 2 packages from 7 contributors and audited 2 packages in 21.89s
found 0 vulnerabilities
Concluímos a instalação do RxJS. Vamos agora tentar usar RxJS, para isso criar uma pastasrc/ dentro rxjsproj/
Então, agora, teremos a estrutura de pastas conforme mostrado abaixo -
rxjsproj/
node_modules/
src/
package.json
Dentro src/ criar um arquivo testrx.jse escreva o seguinte código -
testrx.js
import { of } from 'rxjs;
import { map } from 'rxjs/operators';
map(x => x * x)(of(1, 2, 3)).subscribe((v) => console.log(`Output is: ${v}`));
Quando vamos executar o código acima no prompt de comando, usando o comando - node testrx.js, ele exibirá um erro para importação, pois nodejs não sabe o que fazer com a importação.
Para fazer a importação funcionar com nodejs, precisamos instalar o pacote de módulos ES6 usando npm, conforme mostrado abaixo -
E:\rxjsproj\src>npm install --save-dev esm
npm WARN [email protected] No description
npm WARN [email protected] No repository field.
+ [email protected]
added 1 package from 1 contributor and audited 3 packages in 9.32s
found 0 vulnerabilities
Assim que o pacote estiver instalado, podemos agora executar testrx.js arquivo como mostrado abaixo -
E:\rxjsproj\src>node -r esm testrx.js
Output is: 1
Output is: 4
Output is: 9
Podemos ver a saída agora, que mostra que o RxJS está instalado e pronto para uso. O método acima nos ajudará a testar o RxJS na linha de comando. Caso queira testar o RxJS no navegador, precisaríamos de alguns pacotes adicionais.
Testando RxJS no navegador
Instale os seguintes pacotes dentro da pasta / rxjsproj -
npm install --save-dev babel-loader @babel/core @babel/preset-env webpack webpack-cli webpack-dev-server
E:\rxjsproj>npm install --save-dev babel-loader
@babel/core @babel/preset-env webpack webpack-cli webpack-dev-server
npm WARN [email protected] No description
npm WARN [email protected] No repository field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected]
(node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]
1.2.9: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
+ [email protected]
+ [email protected]
+ @babel/[email protected]
+ @babel/[email protected]
+ [email protected]
+ [email protected]
added 675 packages from 373 contributors and audited 10225 packages in 255.567s
found 0 vulnerabilities
Para iniciar o servidor para executar nosso arquivo Html, usaremos o webpack-server. O comando "publicar" no package.json nos ajudará a começar e também a empacotar todos os arquivos js usando o webpack. Os arquivos js compactados, que são o arquivo js final a ser usado, são salvos na pasta path / dev .
Para usar o webpack, precisamos executar npm run publish comando e o comando é adicionado em package.json conforme mostrado abaixo -
Package.json
{
"name": "rxjsproj",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"publish":"webpack && webpack-dev-server --output-public=/dev/",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.6.0",
"@babel/preset-env": "^7.6.0",
"babel-loader": "^8.0.6",
"esm": "^3.2.25",
"rxjs": "^6.5.3",
"webpack": "^4.39.3",
"webpack-cli": "^3.3.8",
"webpack-dev-server": "^3.8.0"
}
}
Para trabalhar com o webpack, devemos primeiro criar um arquivo chamado webpack.config.js que contém os detalhes de configuração para que o webpack funcione.
Os detalhes do arquivo são os seguintes -
var path = require('path');
module.exports = {
entry: {
app: './src/testrx.js'
},
output: {
path: path.resolve(__dirname, 'dev'),
filename: 'main_bundle.js'
},
mode:'development',
module: {
rules: [
{
test:/\.(js)$/,
include: path.resolve(__dirname, 'src'),
loader: 'babel-loader',
query: {
presets: ['@babel/preset-env']
}
}
]
}
};
A estrutura do arquivo é a mostrada acima. Ele começa com um caminho que fornece os detalhes do caminho atual.
var path = require('path'); //gives the current path
Em seguida, vem o objeto module.exports que possui as propriedades de entrada, saída e módulo. A entrada é o ponto de partida. Aqui, precisamos fornecer o arquivo js inicial que queremos compilar.
entry: {
app: './src/testrx.js'
},
path.resolve (_dirname, 'src / testrx.js') - irá procurar a pasta src no diretório e testrx.js nessa pasta.
Resultado
output: {
path: path.resolve(__dirname, 'dev'),
filename: 'main_bundle.js'
},
A saída é um objeto com o caminho e o nome do arquivo details.path irá conter a pasta na qual o arquivo compilado será mantido e o nome do arquivo dirá o nome do arquivo final a ser usado em seu arquivo .html.
Módulo
module: {
rules: [
{
test:/\.(js)$/,
include: path.resolve(__dirname, 'src'),
loader: 'babel-loader',
query: {
presets: ['@babel/preset-env']
}
}
]
}
Moduleé um objeto com detalhes de regras que possui propriedades, ou seja, teste, inclusão, carregador, consulta. O teste conterá detalhes de todos os arquivos js que terminam com .js e .jsx. Ele tem o padrão que procurará .js no final do ponto de entrada fornecido.
Include informa a pasta a ser usada para examinar os arquivos.
The loader usa o babel-loader para compilar o código.
The querypossui predefinições de propriedade que é uma matriz com o valor '@ babel / preset-env'. Ele irá transpilar o código de acordo com o ambiente ES de que você precisa.
A estrutura final da pasta será a seguinte -
rxjsproj/
node_modules/
src/
testrx.js
index.html
package.json
webpack.config.js
Comando de execução
npm run publishirá criar dev / folder com o arquivo main_bundle.js nele. O servidor será iniciado e você pode testar seu index.html no navegador conforme mostrado abaixo.
Abra o navegador e acesse o url - http://localhost:8080/
A saída é mostrada no console.
Estamos usando o RxJS versão 6 neste tutorial. RxJS é comumente usado para lidar com programação reativa e mais frequentemente com Angular, ReactJS. Angular 6 carrega rxjs6 por padrão.
O RxJS versão 5 foi tratado de forma diferente em comparação com a versão 6. O código será interrompido caso você atualize seu RxJS 5 para 6. Neste capítulo, veremos a diferença nas maneiras de lidar com a atualização da versão.
Caso você esteja atualizando o RxJS para 6 e não queira fazer as alterações no código, você também pode fazer isso e terá que instalar o seguinte pacote.
npm install --save-dev rxjs-compact
Este pacote se encarregará de fornecer compatibilidade com versões anteriores e o código antigo funcionará bem com o RxJS versão 6. Se você deseja fazer as alterações de código que funcionam bem com o RxJS 6, aqui estão as alterações que precisam ser feitas.
Os pacotes para operadores, observáveis, assunto foram reestruturados e, portanto, as principais mudanças vão para as importações e são explicadas a seguir.
Importações para operadoras
De acordo com a versão 5, para os operadores, as seguintes declarações de importação devem ser incluídas -
import 'rxjs/add/operator/mapTo'
import 'rxjs/add/operator/take'
import 'rxjs/add/operator/tap'
import 'rxjs/add/operator/map'
Na versão 6 do RxJS as importações serão as seguintes -
import {mapTo, take, tap, map} from "rxjs/operators"
Importação de métodos para criar observáveis
De acordo com a versão 5, ao trabalhar com Observáveis, os seguintes métodos de importação devem ser incluídos -
import "rxjs/add/observable/from";
import "rxjs/add/observable/of";
import "rxjs/add/observable/fromEvent";
import "rxjs/add/observable/interval";
Na versão 6 do RxJS as importações serão as seguintes -
import {from, of, fromEvent, interval} from 'rxjs';
Importação de observáveis
No RxJS versão 5, ao trabalhar com observáveis, as seguintes instruções de importação devem ser incluídas -
import { Observable } from 'rxjs/Observable'
Na versão 6 do RxJS, as importações serão as seguintes -
import { Observable } from 'rxjs'
Importação de Assunto
No RxJS versão 5, o assunto deve ser incluído da seguinte forma -
import { Subject} from 'rxjs/Subject'
Na versão 6 do RxJS, as importações serão as seguintes -
import { Subject } from 'rxjs'
Como usar operadoras no RxJS 6?
pipe() methodestá disponível no observável criado. Ele é adicionado ao RxJS a partir da versão 5.5. Usando pipe () agora você pode trabalhar em vários operadores juntos em ordem sequencial. É assim que os operadores eram usados no RxJS versão 5.
Exemplo
import "rxjs/add/observable/from";
import 'rxjs/add/operator/max'
let list1 = [1, 6, 15, 10, 58, 2, 40];
from(list1).max((a,b)=>a-b).subscribe(x => console.log("The Max value is "+x));
A partir do RxJS versão 5.5 em diante, temos que usar o pipe () para executar o operador -
Exemplo
import { from } from 'rxjs';
import { max } from 'rxjs/operators';
from(list1).pipe(max((a,b)=>a-b)).subscribe(x => console.log(
"The Max value is "+x)
);
Operadores renomeados
Durante a reestruturação dos pacotes, alguns dos operadores foram renomeados, pois estavam em conflito ou correspondiam a palavras-chave javascript. A lista é mostrada abaixo -
Operador | Renomeado para |
---|---|
Faz() | toque() |
pegar() | catchError () |
interruptor() | switchAll () |
finalmente() | finalizar() |
lançar() | throwError () |
Um observável é uma função que cria um observador e o anexa à fonte de onde os valores são esperados, por exemplo, cliques, eventos de mouse de um elemento dom ou uma solicitação Http, etc.
Observer is an object with callback functions, que será chamado quando houver interação com o Observable, ou seja, a fonte interagiu para um exemplo de clique de botão, solicitação Http, etc.
Vamos discutir os seguintes tópicos neste capítulo -
- Criar observável
- Inscrever-se observável
- Executar observável
Criar observável
O observável pode ser criado usando o construtor observável e também usando o método de criação observável e passando a função de inscrição como um argumento para ela, conforme mostrado abaixo -
testrx.js
import { Observable } from 'rxjs';
var observable = new Observable(
function subscribe(subscriber) {
subscriber.next("My First Observable")
}
);
Criamos um observável e adicionamos uma mensagem "Meu primeiro observável" usando subscriber.next método disponível dentro do Observable.
Também podemos criar Observable usando o método Observable.create () conforme mostrado abaixo -
testrx.js
import { Observable } from 'rxjs';
var observer = Observable.create(
function subscribe(subscriber) {
subscriber.next("My First Observable")
}
);
Inscrever-se observável
Você pode se inscrever em um observável da seguinte forma -
testrx.js
import { Observable } from 'rxjs';
var observer = new Observable(
function subscribe(subscriber) {
subscriber.next("My First Observable")
}
);
observer.subscribe(x => console.log(x));
Quando o observador estiver inscrito, ele iniciará a execução do Observable.
Isso é o que vemos no console do navegador -
Executar observável
Um observável é executado quando é inscrito. Um observador é um objeto com três métodos que são notificados,
next() - Este método enviará valores como um número, string, objeto etc.
complete() - Este método não enviará nenhum valor e indica o observável como concluído.
error() - Este método enviará o erro se houver.
Vamos criar o observável com todas as três notificações e executar o mesmo.
testrx.js
import { Observable } from 'rxjs';
var observer = new Observable(
function subscribe(subscriber) {
try {
subscriber.next("My First Observable");
subscriber.next("Testing Observable");
subscriber.complete();
} catch(e){
subscriber.error(e);
}
}
);
observer.subscribe(x => console.log(x), (e)=>console.log(e),
()=>console.log("Observable is complete"));
No código acima, adicionamos os métodos next, complete e error.
try{
subscriber.next("My First Observable");
subscriber.next("Testing Observable");
subscriber.complete();
} catch(e){
subscriber.error(e);
}
Para executar next, complete e error, temos que chamar o método subscribe conforme mostrado abaixo -
observer.subscribe(x => console.log(x), (e)=>console.log(e),
()=>console.log("Observable is complete"));
O método de erro será invocado apenas se houver um erro.
Esta é a saída vista no navegador -
Os operadores são uma parte importante do RxJS. Um operador é uma função pura que recebe observáveis como entrada e a saída também é observável.
Trabalhando com Operadores
Um operador é uma função pura que recebe observável como entrada e a saída também é observável.
Para trabalhar com operadores, precisamos de um método pipe ().
Exemplo de uso de pipe ()
let obs = of(1,2,3); // an observable
obs.pipe(
operator1(),
operator2(),
operator3(),
operator3(),
)
No exemplo acima, criamos um observável usando of()método que leva os valores 1, 2 e 3. Agora, neste observável, você pode executar diferentes operações usando qualquer número de operadores usando o método pipe () conforme mostrado acima. A execução dos operadores continuará sequencialmente no observável dado.
Abaixo está um exemplo de trabalho -
import { of } from 'rxjs';
import { map, reduce, filter } from 'rxjs/operators';
let test1 = of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
let case1 = test1.pipe(
filter(x => x % 2 === 0),
reduce((acc, one) => acc + one, 0)
)
case1.subscribe(x => console.log(x));
Resultado
30
No exemplo acima, usamos o operador de filtro que filtra os números pares e, a seguir, usamos reduce() operador que irá adicionar os valores pares e dar o resultado quando inscrito.
Aqui está uma lista de observáveis que iremos discutir.
- Creation
- Mathematical
- Join
- Transformation
- Filtering
- Utility
- Conditional
- Multicasting
- Manipulação de erros
Operadores de criação
A seguir estão os operadores que vamos discutir na categoria de operador de criação -
Sr. Não | Operador e descrição |
---|---|
1 | Ajax Este operador fará uma solicitação ajax para o URL fornecido. |
2 | de Este operador criará um observável a partir de uma matriz, um objeto semelhante a uma matriz, uma promessa, um objeto iterável ou um objeto semelhante a um observável. |
3 | fromEvent Este operador dará saída como um observável que deve ser usado em elementos que emitem um evento, por exemplo, botões, cliques, etc. |
4 | fromEventPattern Este operador criará um observável a partir da função de entrada que é usada para registrar manipuladores de eventos. |
5 | intervalo Este operador criará um Observável para cada vez durante o tempo fornecido. |
6 | do Este operador pegará os argumentos passados e os converterá em observáveis. |
7 | alcance Este operador criará um Observable que fornecerá uma sequência de números com base no intervalo fornecido. |
8 | throwError Este operador criará um observável que notificará um erro. |
9 | cronômetro Este operador criará um observável que emitirá o valor após o tempo limite e o valor continuará aumentando após cada chamada. |
10 | se Este operador decidirá qual Observable será inscrito. |
Operadores matemáticos
A seguir estão os operadores que vamos discutir na categoria Operador matemático -
Sr. Não | Operador e descrição |
---|---|
1 | Contagem O operador count () obtém um Observable com valores e o converte em um Observable que fornecerá um único valor |
2 | Max O método Max pegará um observável com todos os valores e retornará um observável com o valor máximo |
3 | Min O método Min pegará um observável com todos os valores e retornará um observável com o valor mínimo. |
4 | Reduzir No operador de redução, a função de acumulador é usada na entrada observável, e a função de acumulador retornará o valor acumulado na forma de um observável, com um valor semente opcional passado para a função de acumulador. A função reduz () terá 2 argumentos, uma função acumuladora e, em seguida, o valor da semente. |
Operadores de adesão
A seguir estão os operadores que discutiremos na categoria de operador Join.
Sr. Não | Operador e descrição |
---|---|
1 | concat Este operador emitirá sequencialmente o Observable fornecido como entrada e prosseguirá para o próximo. |
2 | forkJoin Este operador será obtido em uma matriz ou objeto dict como uma entrada e aguardará a conclusão do observável e retornará os últimos valores emitidos do observável fornecido. |
3 | fundir Este operador pegará a entrada observável e emitirá todos os valores do observável e emitirá uma única saída observável. |
4 | raça Ele retornará um observável que será uma cópia espelhada da primeira fonte observável. |
Operadores de transformação
A seguir estão os operadores que discutiremos na categoria Operador de transformação.
Sr. Não | Operador e descrição |
---|---|
1 | amortecedor O buffer opera em um observável e aceita o argumento como um observável. Ele começará a armazenar em buffer os valores emitidos em seu observável original em uma matriz e emitirá o mesmo quando o observável tomado como argumento emite. Uma vez que o observável tomado como argumento seja emitido, o buffer é zerado e começa a fazer o buffer novamente no original até que o observável de entrada seja emitido e o mesmo cenário se repita. |
2 | bufferCount No caso do operador buffercount (), ele coletará os valores do observável no qual é chamado e emitirá os mesmos quando o tamanho do buffer fornecido para buffercount corresponder. |
3 | tempo de atraso Isso é semelhante a bufferCount, portanto, aqui, ele coletará os valores do observável no qual é chamado e emitirá o bufferTimeSpan. Recebe 1 argumento, ou seja, bufferTimeSpan . |
4 | bufferToggle No caso de bufferToggle () leva 2 argumentos, openings e fechandoSelector. Os argumentos de abertura são assináveis ou uma promessa de iniciar o buffer e o segundo argumento fechamentoSelector é novamente assinável ou promete um indicador para fechar o buffer e emitir os valores coletados. |
5 | bufferWhen Este operador fornecerá os valores na forma de array, ele recebe um argumento como uma função que decidirá quando fechar, emitir e redefinir o buffer. |
6 | expandir O operador de expansão recebe uma função como um argumento que é aplicado na fonte observável recursivamente e também na saída observável. O valor final é observável. |
7 | groupBy No operador groupBy, a saída é agrupada com base em uma condição específica e esses itens de grupo são emitidos como GroupedObservable. |
8 | mapa No caso do operador de mapa, uma função de projeto é aplicada em cada valor na fonte Observable e a mesma saída é emitida como um Observable. |
9 | mapa para Um valor constante é fornecido como saída junto com o Observable sempre que a fonte Observable emite um valor. |
10 | mergeMap No caso do operador mergeMap, uma função de projeto é aplicada em cada valor de origem e a saída dele é mesclada com a saída Observable. |
11 | switchMap No caso do operador switchMap, uma função de projeto é aplicada em cada valor de origem e a saída dele é mesclada com a saída Observable, e o valor fornecido é o Observable projetado mais recente. |
12 | janela Recebe um argumento windowboundaries que é um observável e devolve um observável aninhado sempre que os limites da janela emite |
Operadores de filtragem
A seguir estão os operadores que discutiremos na categoria de operador de filtragem.
Sr. Não | Operador e descrição |
---|---|
1 | debounce Um valor emitido da fonte Observável após um tempo e a emissão é determinada por outra entrada dada como Observável ou promessa. |
2 | debounceTime Ele emitirá um valor da fonte observável somente depois que o tempo for concluído. |
3 | distinto Este operador fornecerá todos os valores observáveis de origem que são distintos quando comparados com o valor anterior. |
4 | elementAt Este operador fornecerá um único valor da fonte observável com base no índice fornecido. |
5 | filtro Este operador filtrará os valores da fonte Observable com base na função de predicado fornecida. |
6 | primeiro Este operador dará o primeiro valor emitido pela fonte Observable. |
7 | último Este operador dará o último valor emitido pela fonte Observable. |
8 | ignoreElements Este operador irá ignorar todos os valores da fonte Observable e apenas executará chamadas para completar ou funções de callback de erro. |
9 | amostra Este operador fornecerá o valor mais recente da fonte Observable e a saída dependerá do argumento transmitido a ele emite. |
10 | pular Este operador retornará um observável que ignorará a primeira ocorrência de itens de contagem tomados como entrada. |
11 | acelerador Este operador emitirá e também ignorará os valores da fonte observáveis pelo tempo determinado pela função de entrada tomada como um argumento e o mesmo processo será repetido. |
Operadores de serviços públicos
A seguir estão os operadores que discutiremos na categoria de operadores de serviços públicos.
Sr. Não | Operador e descrição |
---|---|
1 | toque Este operador terá a saída, igual ao observável de origem, e pode ser usado para registrar os valores do observável para o usuário. O valor principal, erro se houver ou se a tarefa foi concluída. |
2 | demora Este operador atrasa os valores emitidos da fonte Observable com base no tempo limite fornecido. |
3 | atrasar quando Este operador atrasa os valores emitidos da fonte Observável com base no tempo limite de outro observável tomado como entrada. |
4 | observeOn Este operador baseado no agendador de entrada irá reemitir as notificações da fonte Observable. |
5 | subscribeOn Este operador ajuda a assinantes assíncronos para a fonte Observable com base no planejador considerado como entrada. |
6 | intervalo de tempo Este operador retornará um objeto que contém o valor atual e o tempo decorrido entre o valor atual e o anterior que é calculado usando a entrada do planejador obtida. |
7 | timestamp Retorna o carimbo de data / hora junto com o valor emitido da fonte Observable, que informa sobre a hora em que o valor foi emitido. |
8 | tempo esgotado Este operador lançará um erro se a fonte Observable não emitir um valor após o tempo limite fornecido. |
9 | toArray Acumula todos os valores de origem do Observable e os produz como uma matriz quando a origem é concluída. |
Operadores condicionais
A seguir estão os operadores que discutiremos na categoria de operadores condicionais.
Sr. Não | Operador e descrição |
---|---|
1 | defaultIfEmpty Este operador retornará um valor padrão se a fonte observável estiver vazia. |
2 | cada Ele retornará um Observable com base na função de entrada que satisfaz a condição de cada um dos valores da fonte Observable. |
3 | encontrar Isso retornará o observável quando o primeiro valor da fonte Observável satisfizer a condição para a função de predicado tomada como entrada. |
4 | findIndex Este operador baseado no agendador de entrada irá reemitir as notificações da fonte Observable. |
5 | está vazia Este operador dará a saída como verdadeira se a entrada observável for para um retorno de chamada completo sem emitir nenhum valor e falso se a entrada observável emitir qualquer valor. |
Operadores multicast
A seguir estão os operadores que discutiremos na categoria de operadores multicast.
Sr. Não | Operador e descrição |
---|---|
1 | multicast Um operador multicast compartilha a única assinatura criada com outros assinantes. Os parâmetros que o multicast recebe, é um assunto ou um método de fábrica que retorna um ConnectableObservable que tem o método connect (). Para se inscrever, o método connect () deve ser chamado. |
2 | publicar Este operador retorna ConnectableObservable e precisa usar o método connect () para assinar os observáveis. |
3 | publishBehavior publishBehaviour usa BehaviourSubject e retorna ConnectableObservable. O método connect () deve ser usado para assinar o observável criado. |
4 | publicarLast publishBehaviour faz uso de AsyncSubject e retorna ConnectableObservable. O método connect () deve ser usado para assinar o observável criado. |
5 | publicarReplay publishReplay faz uso de assunto de comportamento em que pode armazenar os valores e reproduzir os mesmos para os novos assinantes e retorna ConnectableObservable. O método connect () deve ser usado para assinar o observável criado. |
6 | compartilhar É um alias para o operador mutlicast (), com a única diferença que você não precisa chamar o método connect () manualmente para iniciar a assinatura. |
Operadores de tratamento de erros
A seguir estão os operadores que discutiremos na categoria de operadores de tratamento de erros.
Sr. Não | Operador e descrição |
---|---|
1 | catchError Este operador se encarrega de detectar erros na fonte Observable, retornando um novo Observable ou um erro. |
2 | tentar novamente Este operador se encarregará de tentar novamente na fonte Observável se houver erro e a nova tentativa será feita com base na contagem de entrada fornecida. |
Quando o observável é criado, para executar o observável, precisamos assiná-lo.
operador count ()
Aqui está um exemplo simples de como se inscrever em um observável.
Exemplo 1
import { of } from 'rxjs';
import { count } from 'rxjs/operators';
let all_nums = of(1, 7, 5, 10, 10, 20);
let final_val = all_nums.pipe(count());
final_val.subscribe(x => console.log("The count is "+x));
Resultado
The count is 6
A assinatura tem um método chamado unsubscribe (). Uma chamada ao método unsubscribe () removerá todos os recursos usados para aquele observável, ou seja, o observável será cancelado. Aqui está um exemplo prático do uso do método unsubscribe ().
Exemplo 2
import { of } from 'rxjs';
import { count } from 'rxjs/operators';
let all_nums = of(1, 7, 5, 10, 10, 20);
let final_val = all_nums.pipe(count());
let test = final_val.subscribe(x => console.log("The count is "+x));
test.unsubscribe();
A assinatura é armazenada no teste de variável. Usamos test.unsubscribe () o observável.
Resultado
The count is 6
Um assunto é um observável que pode transmitir, ou seja, falar com muitos observadores. Considere um botão com um ouvinte de evento, a função anexada ao evento usando adicionar ouvinte é chamada toda vez que o usuário clica no botão, uma funcionalidade semelhante também vai para o assunto.
Vamos discutir os seguintes tópicos neste capítulo -
- Crie um assunto
- Qual é a diferença entre observável e sujeito?
- Assunto Comportamento
- Assunto Repetir
- AsyncSubject
Crie um assunto
Para trabalhar com assunto, precisamos importar Assunto conforme mostrado abaixo -
import { Subject } from 'rxjs';
Você pode criar um objeto sujeito da seguinte maneira -
const subject_test = new Subject();
O objeto é um observador que possui três métodos -
- next(v)
- error(e)
- complete()
Inscrever-se em um assunto
Você pode criar várias assinaturas sobre o assunto, conforme mostrado abaixo -
subject_test.subscribe({
next: (v) => console.log(`From Subject : ${v}`)
});
subject_test.subscribe({
next: (v) => console.log(`From Subject: ${v}`)
});
A assinatura é registrada para o objeto subject, assim como addlistener que discutimos anteriormente.
Passando Dados para o Assunto
Você pode passar dados para o assunto criado usando o método next ().
subject_test.next("A");
Os dados serão repassados a todas as assinaturas adicionadas no assunto.
Exemplo
Aqui está um exemplo prático do assunto -
import { Subject } from 'rxjs';
const subject_test = new Subject();
subject_test.subscribe({
next: (v) => console.log(`From Subject : ${v}`)
});
subject_test.subscribe({
next: (v) => console.log(`From Subject: ${v}`)
});
subject_test.next("A");
subject_test.next("B");
O objeto subject_test é criado chamando um novo Subject (). O objeto subject_test faz referência aos métodos next (), error () e complete (). O resultado do exemplo acima é mostrado abaixo -
Resultado
Podemos usar o método complete () para parar a execução do assunto conforme mostrado abaixo.
Exemplo
import { Subject } from 'rxjs';
const subject_test = new Subject();
subject_test.subscribe({
next: (v) => console.log(`From Subject : ${v}`)
});
subject_test.subscribe({
next: (v) => console.log(`From Subject: ${v}`)
});
subject_test.next("A");
subject_test.complete();
subject_test.next("B");
Depois de chamarmos complete, o próximo método chamado mais tarde não é invocado.
Resultado
Vamos agora ver como chamar o método error ().
Exemplo
Abaixo está um exemplo de trabalho -
import { Subject } from 'rxjs';
const subject_test = new Subject();
subject_test.subscribe({
error: (e) => console.log(`From Subject : ${e}`)
});
subject_test.subscribe({
error: (e) => console.log(`From Subject : ${e}`)
});
subject_test.error(new Error("There is an error"));
Resultado
Qual é a diferença entre observável e sujeito?
Um observável falará um a um, com o assinante. Sempre que você assinar o observável, a execução começará do zero. Faça uma chamada Http feita usando ajax e 2 assinantes chamando o observable. Você verá 2 solicitações HttpHttp na guia de rede do navegador.
Exemplo
Aqui está um exemplo prático do mesmo -
import { ajax } from 'rxjs/ajax';
import { map } from 'rxjs/operators';
let final_val = ajax('https://jsonplaceholder.typicode.com/users').pipe(map(e => e.response));
let subscriber1 = final_val.subscribe(a => console.log(a));
let subscriber2 = final_val.subscribe(a => console.log(a));
Resultado
Agora, aqui o problema é, queremos que os mesmos dados sejam compartilhados, mas não, ao custo de 2 chamadas Http. Queremos fazer uma chamada Http e compartilhar os dados entre os assinantes.
Isso será possível usando Assuntos. É um observável que pode transmitir, ou seja, conversar com muitos observadores. Ele pode compartilhar o valor entre os assinantes.
Exemplo
Aqui está um exemplo de trabalho usando assuntos -
import { Subject } from 'rxjs';
import { ajax } from 'rxjs/ajax';
import { map } from 'rxjs/operators';
const subject_test = new Subject();
subject_test.subscribe({
next: (v) => console.log(v)
});
subject_test.subscribe({
next: (v) => console.log(v)
});
let final_val = ajax('https://jsonplaceholder.typicode.com/users').pipe(map(e => e.response));
let subscriber = final_val.subscribe(subject_test);
Resultado
Agora você pode ver apenas uma chamada Http e os mesmos dados são compartilhados entre os assinantes chamados.
Assunto Comportamento
O assunto de comportamento fornecerá o valor mais recente quando chamado.
Você pode criar um assunto de comportamento conforme mostrado abaixo -
import { BehaviorSubject } from 'rxjs';
const subject = new BehaviorSubject("Testing Behaviour Subject");
// initialized the behaviour subject with value:Testing Behaviour Subject
Exemplo
Aqui está um exemplo prático para usar o Assunto Comportamento -
import { BehaviorSubject } from 'rxjs';
const behavior_subject = new BehaviorSubject("Testing Behaviour Subject");
// 0 is the initial value
behavior_subject.subscribe({
next: (v) => console.log(`observerA: ${v}`)
});
behavior_subject.next("Hello");
behavior_subject.subscribe({
next: (v) => console.log(`observerB: ${v}`)
});
behavior_subject.next("Last call to Behaviour Subject");
Resultado
Assunto Repetir
Um sujeito de replay é semelhante ao sujeito de comportamento, em que ele pode armazenar os valores e reproduzir os mesmos para os novos assinantes.
Exemplo
Aqui está um exemplo prático de assunto de repetição -
import { ReplaySubject } from 'rxjs';
const replay_subject = new ReplaySubject(2);
// buffer 2 values but new subscribers
replay_subject.subscribe({
next: (v) => console.log(`Testing Replay Subject A: ${v}`)
});
replay_subject.next(1);
replay_subject.next(2);
replay_subject.next(3);
replay_subject.subscribe({
next: (v) => console.log(`Testing Replay Subject B: ${v}`)
});
replay_subject.next(5);
O valor do buffer usado é 2 no assunto de reprodução. Portanto, os dois últimos valores serão armazenados em buffer e usados para os novos assinantes chamados.
Resultado
AsyncSubject
No caso de AsyncSubject, o último valor chamado é passado para o assinante e isso será feito somente após o método complete () ser chamado.
Exemplo
Aqui está um exemplo prático do mesmo -
import { AsyncSubject } from 'rxjs';
const async_subject = new AsyncSubject();
async_subject.subscribe({
next: (v) => console.log(`Testing Async Subject A: ${v}`)
});
async_subject.next(1);
async_subject.next(2);
async_subject.complete();
async_subject.subscribe({
next: (v) => console.log(`Testing Async Subject B: ${v}`)
});
Aqui, antes que complete é chamado, o último valor passado ao assunto é 2 e o mesmo que é dado aos assinantes.
Resultado
Um planejador controla a execução de quando a assinatura deve ser iniciada e notificada.
Para fazer uso do planejador, precisamos do seguinte -
import { Observable, asyncScheduler } from 'rxjs';
import { observeOn } from 'rxjs/operators';
Aqui está um exemplo de trabalho, onde usaremos o escalonador que decidirá a execução.
Exemplo
import { Observable, asyncScheduler } from 'rxjs';
import { observeOn } from 'rxjs/operators';
var observable = new Observable(function subscribe(subscriber) {
subscriber.next("My First Observable");
subscriber.next("Testing Observable");
subscriber.complete();
}).pipe(
observeOn(asyncScheduler)
);
console.log("Observable Created");
observable.subscribe(
x => console.log(x),
(e)=>console.log(e),
()=>console.log("Observable is complete")
);
console.log('Observable Subscribed');
Resultado
Sem o planejador, a saída teria sido conforme mostrado abaixo -
Neste capítulo, veremos como usar RxJs com Angular. Não entraremos no processo de instalação do Angular aqui, para saber sobre a instalação do Angular consulte este link -
Vamos trabalhar diretamente em um exemplo, onde usaremos Ajax do RxJS para carregar os dados.
Exemplo
app.component.ts
import { Component } from '@angular/core';
import { environment } from './../environments/environment';
import { ajax } from 'rxjs/ajax';
import { map } from 'rxjs/operators'
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = '';
data;
constructor() {
this.data = "";
this.title = "Using RxJs with Angular";
let a = this.getData();
}
getData() {
const response =
ajax('https://jsonplaceholder.typicode.com/users')
.pipe(map(e => e.response));
response.subscribe(res => {
console.log(res);
this.data = res;
});
}
}
app.component.html
<div>
<h3>{{title}}</h3>
<ul *ngFor="let i of data">
<li>{{i.id}}: {{i.name}}</li>
</ul>
</div>
<router-outlet></router-outlet>
Usamos o ajax do RxJS que irá carregar os dados deste url -https://jsonplaceholder.typicode.com/users.
Quando você compila a exibição é como mostrado abaixo -
Neste capítulo, veremos como usar RxJs com ReactJS. Não entraremos no processo de instalação do Reactjs aqui, para saber sobre a instalação do ReactJS consulte este link:
Exemplo
Trabalharemos diretamente em um exemplo abaixo, onde usaremos Ajax do RxJS para carregar dados.
index.js
import React, { Component } from "react";
import ReactDOM from "react-dom";
import { ajax } from 'rxjs/ajax';
import { map } from 'rxjs/operators';
class App extends Component {
constructor() {
super();
this.state = { data: [] };
}
componentDidMount() {
const response = ajax('https://jsonplaceholder.typicode.com/users').pipe(map(e => e.response));
response.subscribe(res => {
this.setState({ data: res });
});
}
render() {
return (
<div>
<h3>Using RxJS with ReactJS</h3>
<ul>
{this.state.data.map(el => (
<li>
{el.id}: {el.name}
</li>
))}
</ul>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset = "UTF-8" />
<title>ReactJS Demo</title>
<head>
<body>
<div id = "root"></div>
</body>
</html>
Usamos o ajax do RxJS que irá carregar os dados deste Url -https://jsonplaceholder.typicode.com/users.
Quando você compila, a exibição é como mostrado abaixo -