Engenharia reversa Observável

Indermohan Singh Blocked Unblock Seguir Seguindo 11 de janeiro

TL; DR: Neste artigo, faremos a engenharia reversa Observable da biblioteca RxJS . Também recriaremos alguns operadores da biblioteca e aprenderemos sobre Observer e Subscription. Também vamos usar o TypeScript para anotar o código. No final, vamos escrever um código de exemplo muito pequeno para usar essa biblioteca de engenharia reversa. Você pode encontrar a demonstração no StackBlitz .

Introdução à Programação Reativa e RxJS

Vamos simplificar.

  • Programação reativa é programação com fluxos de dados assíncronos – Andre Staltz (criador do cycle.js )

Eu não vou lhe dar uma longa explicação neste post (você pode encontrar mais informações aqui ), mas a Programação Reativa é basicamente um paradigma (ou abordagem) para gerenciar fluxos de dados assíncronos.

RxJS é uma biblioteca para fazer a programação reativa. Ele permite que você escreva programas reativos com uma abordagem funcional.

O que é observável?

Observável é o elemento central do RxJS. É mais ou menos como uma matriz, cujos itens chegam no futuro de forma assíncrona.

  • Observável representa a ideia de uma coleção invocável de valores ou eventos futuros. – RxJS Docs

Da perspectiva da API, o Observable possui um método de inscrição . Este método de inscrição é usado para invocar a execução de um Observable.

No exemplo acima, criamos um Observable chamado observable usando algum código rxjs mágico e então invocamos o método subscribe passando doSomething. Uma coisa importante a lembrar é quando chamamos este método de assinatura apenas, o Observable começa a funcionar. Por enquanto, ignore como criamos o observável e o que o doesSomething é.

Também é importante notar que este método de assinatura retorna algo chamado Subscription . Basicamente, esta assinatura nos permite cancelar a assinatura do Observable. Em outras palavras, ele retorna um objeto com um método de cancelamento de inscrição , o que nos permite parar de ouvir os valores enviados por Observable.

O que é o Observer?

Observador é uma coleção de funções de retorno de chamada, que reage ao valor que chega via Observable.

  • O Observer é uma coleção de retornos de chamada que sabe como ouvir os valores entregues pelo Observable. – RxJS Docs.

Em Observable, precisamos de callbacks para três coisas:

  • valoresvalores futuros, que o Observable vai enviar / enviar
  • erros – erros que podem ocorrer enquanto a invocação de um Observável para sinalizar quando observável é feita com o envio de valores

Portanto, o Observer é uma coleção de três métodos de retorno de chamada, conforme mostrado abaixo:

O método de assinatura e o Observer

Existe uma relação entre o método Observer e subscribe. Dê uma olhada no seguinte exemplo:

Aqui, nós criamos um Observable e então o executamos chamando o método subscribe . E se você der uma olhada mais de perto, nós passamos um Observer para esse método de assinatura.

Você pode escrever a definição de tipo de assinatura no TypeScript da seguinte maneira:

Observable.subscribe(observer:Observer):Subscription;

Você pode combinar esse padrão com qualquer API Push.

Usando o padrão Observable and Observer

No exemplo a seguir, vamos incluir o Observable em torno da API setInterval do JavaScript:

Agora podemos chamar este método setIntervalObservable com o tempo e inscrevê-lo. Ele irá disparar o observador. Depois do retorno de chamada após cada ciclo de tempo dado como mostrado abaixo:

Engenharia reversa Observável

Até agora você aprendeu sobre Observer, Observable, Subscription e assim por diante. Agora vamos criar o Observable usando Classes e Interfaces do TypeScript.

Criando interface do observador

Observador, como mencionado, é uma coleção de retornos de chamada. Você já sabe sobre next , error e complete, mas existe um valor opcional chamado closed . O que você vai usar mais tarde neste tutorial:

Criando classe de assinatura

Como mencionado acima, o método de assinatura retorna uma assinatura . Então, basicamente, uma assinatura toma o método unsubscribe como entrada, para que possa ser invocado pelo usuário mais tarde:

Criando classe observável

Nesta seção, criaremos uma classe Observable e um construtor que usa o método subscribe como entrada. O método de inscrição leva o Observer como entrada e retorna uma assinatura:

Criando criar método estático na classe Observable

Observable também vem com um método estático chamado create para criar novo Observable. Esse método também usa um método de inscrição e retorna um Observable:

Operadores de criação de RxJS

Geralmente, ao trabalhar com o RxJS, você não precisa criar seu próprio Observable personalizado. O RxJS vem com métodos de criação que permitem criar Observable a partir de diferentes tipos de Inputs. A entrada para o método de criação pode ser qualquer coisa dependendo das necessidades, mas deve retornar um Observável.

Você pode descrever os operadores de criação usando o TypeScript da seguinte maneira:

creationOperator(input:any): Observable;

Há tantos operadores de criação em RxJS como fromEvent e de para citar alguns.

setIntervalObservable (que usamos anteriormente) é na verdade um método de criação. Podemos facilmente reescrevê-lo usando nossa classe Observable and Subscription como mostrado abaixo:

Engenharia reversa do operador de criação

O operador de criação de RxJS basicamente assume vários valores como uma entrada e, em seguida, envia / envia esses valores para o observador, conforme mostrado abaixo:

Temos que fazer o seguinte:

  • loop sobre cada valor dado como entrada
  • observador de fogo. em seguida com esses valores
  • depois disso, fogo observer.complete ()
  • retornar uma assinatura

Aqui está o código completo para o de operador:

Como criar um operador de criação personalizada?

Criar operadores de criação personalizados é algo como isto:

  • operador pode ter qualquer número ou tipo de entradas, dependendo da necessidade
  • Deve devolver um Observable
  • enviar / enviar valores invocando observer.next
  • Depois de observável está completo, fogo observer.complete ()
  • Não se esqueça de devolver uma Assinatura de dentro do Observable

Operadores Pipeable em RxJS

Até agora, criamos o Observable e nos inscrevemos nele. Mas há outro grande elemento do RxJS que nos permite fazer programação funcional com valores assíncronos. Portanto, podemos basicamente usar o mapa, filtro ou métodos / operadores similares da Array para modificar o Observable original.

Para trabalhar com esses operadores, há um método no pipe nomeado da classe Observable . Esse método de pipe usa um ou vários operadores como uma entrada e retorna um novo Observable:

Observable.pipe(...invokedOperators): Observable;

Aqui está um exemplo de uso de um operador de filtro e mapa no RxJS:

Criando operadores pipetáveis personalizados

Você deve primeiro entender a estrutura e a anatomia do operador de tubulação RxJS para escrever nosso próprio método de tubulação personalizado na classe Observable.

A definição de tipo de um operador pipável usando o TypeScript seria algo como isto:

type pipeableOperator = (input) => (source:Observable) => Observable;

  • operador leva uma entrada. Essa entrada pode ser qualquer coisa e um valor único ou múltiplo. Depende do tipo de operador que você quer fazer.
  • a função do operador retorna outra função. Essa função retornada considera a origem Observable como uma entrada e retorna um novo Observable modificando a entrada executando a ação desejada com base na entrada do operador.

Criando operador de filtro

Para criar um operador de filtro, vamos primeiro ver sua estrutura:

filter(filterPredicate): (source:Observable) => Observable;

  1. filterPredicate é a função que retorna um valor booleano. Você tem que aplicá-lo ao valor emitido pela fonte Observable.
  2. Podemos acessar os valores emitidos pela fonte Observable assinando-a, conforme mostrado abaixo:

3. Dentro da condição if mostrada acima, emita o valor para o novo Observable.

Aqui está como podemos codificar o operador de filtro:

  • Da mesma forma, você pode criar outros operadores, como mapa e assim por diante.

Criando o método de pipe

Agora podemos fazer engenharia reversa do método de tubulação . Mas primeiro temos que fazer o seguinte:

  1. O método Pipe usa entradas únicas ou múltiplas. Então temos que fazer um loop sobre todos esses operadores. Nós podemos usar o operador propagação de JavaScript e foreach para fazer isso, como mostrado abaixo:

2. É importante perceber que, dentro do método de tubulação, nós realmente não conseguimos o operador de tubulação, mas a invocação dele. Em outras palavras, estamos basicamente acessando o que é retornado pelo operador. É uma função que pega a fonte Observable e retorna o novo Observable modificado.

3. Podemos acessar a fonte Observable via isso.

4. Basicamente, começaremos com isso como primeiro Observable e depois chamaremos o primeiro operador. Usaremos esse novo Observable como fonte para o próximo operador.

Aqui está como vamos escrever o método de tubo:

Exemplo final

Aqui está um exemplo de criação e consumo de um Observable usando nossa biblioteca de engenharia reversa:

A parte divertida é que o código no exemplo acima é totalmente compatível com o RxJS. Então basicamente você pode mudar as importações para a biblioteca RxJS e tudo vai funcionar bem.

Conclusão

Neste artigo, escrevemos um subconjunto muito pequeno de RxJS Observable, criando operadores de criação personalizados e operadores de pipetagem personalizados, juntamente com engenharia reversa do operador, operador de filtro do RxJS. Também aprendemos sobre Observador e Assinaturas . Você pode verificar a demonstração no StackBlitz .

Plug: LogRocket , um DVR para aplicativos da web

https://logrocket.com/signup/

LogRocket é uma ferramenta de registro de front-end que permite que você repita problemas como se eles tivessem ocorrido em seu próprio navegador. Em vez de adivinhar por que os erros ocorrem ou solicitar aos usuários capturas de tela e log dumps, o LogRocket permite que você repita a sessão para entender rapidamente o que deu errado. Ele funciona perfeitamente com qualquer aplicativo, independentemente do framework, e possui plugins para registrar o contexto adicional do Redux, Vuex e @ ngrx / store.

Além de registrar as ações e o estado do Redux, o LogRocket registra logs do console, erros de JavaScript, rastreamentos de pilha, solicitações / respostas de rede com cabeçalhos + corpos, metadados do navegador e logs personalizados. Ele também instrumenta o DOM para gravar o HTML e CSS na página, recriando vídeos com pixels perfeitos até mesmo dos aplicativos de página única mais complexos.

Experimente Grátis.