{"id":6194,"date":"2018-12-20T16:07:04","date_gmt":"2018-12-21T00:07:04","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=6194"},"modified":"2024-08-30T02:28:32","modified_gmt":"2024-08-30T09:28:32","slug":"exploring-rxjava-wrapping-listener-callback","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/pt\/exploring-rxjava-wrapping-listener-callback\/","title":{"rendered":"Explorando o RxJava - Envolvendo um retorno de chamada do ouvinte"},"content":{"rendered":"<div id=\"preamble\">\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<div id=\"preamble\">\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p><span class=\"image\"><a class=\"image\" title=\"https:\/\/www.couchbase.com\/downloads\" href=\"https:\/\/www.couchbase.com\/blog\/pt\/downloads\/\"><img decoding=\"async\" src=\"https:\/\/img.shields.io\/badge\/Couchbase%20Lite-v2.1-red.svg\" alt=\"Couchbase%20Lite v2.1 red\" \/><\/a><\/span><\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Nesta publica\u00e7\u00e3o, mostrarei como converter uma API de estilo de ouvinte baseada em callback em uma API reativa com o RxJava 2.<\/p>\n<\/div>\n<div id=\"toc\" class=\"toc\">\n<div id=\"toctitle\" class=\"title\">Conte\u00fado<\/div>\n<ul class=\"sectlevel1\">\n<li><a title=\"vscode-resource:\/Users\/hod\/work\/content\/blog\/blog-source-code\/Greeley\/0052RxListener\/blogpost.adoc#_introduction\" href=\"#_introduction\">Introdu\u00e7\u00e3o<\/a><\/li>\n<li><a title=\"vscode-resource:\/Users\/hod\/work\/content\/blog\/blog-source-code\/Greeley\/0052RxListener\/blogpost.adoc#_objective\" href=\"#_objective\">Objetivo<\/a><\/li>\n<li><a title=\"vscode-resource:\/Users\/hod\/work\/content\/blog\/blog-source-code\/Greeley\/0052RxListener\/blogpost.adoc#_getting_started\" href=\"#_getting_started\">Primeiros passos<\/a><\/li>\n<li><a title=\"vscode-resource:\/Users\/hod\/work\/content\/blog\/blog-source-code\/Greeley\/0052RxListener\/blogpost.adoc#_creating_a_source\" href=\"#_creating_a_source\">Criando uma fonte<\/a>\n<ul class=\"sectlevel4\">\n<li><a title=\"vscode-resource:\/Users\/hod\/work\/content\/blog\/blog-source-code\/Greeley\/0052RxListener\/blogpost.adoc#_listing_basicsource_java\" href=\"#_listing_basicsource_java\">Listagem: BasicSource.java<\/a><\/li>\n<li><a title=\"vscode-resource:\/Users\/hod\/work\/content\/blog\/blog-source-code\/Greeley\/0052RxListener\/blogpost.adoc#_listing_unboundsource_java\" href=\"#_listing_unboundsource_java\">Listagem: UnboundSource.java<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a title=\"vscode-resource:\/Users\/hod\/work\/content\/blog\/blog-source-code\/Greeley\/0052RxListener\/blogpost.adoc#_converting_to_an_observable\" href=\"#_converting_to_an_observable\">Convers\u00e3o para um observ\u00e1vel<\/a>\n<ul class=\"sectlevel4\">\n<li><a title=\"vscode-resource:\/Users\/hod\/work\/content\/blog\/blog-source-code\/Greeley\/0052RxListener\/blogpost.adoc#_listing_observables_java\" href=\"#_listing_observables_java\">Listagem: Observables.java<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a title=\"vscode-resource:\/Users\/hod\/work\/content\/blog\/blog-source-code\/Greeley\/0052RxListener\/blogpost.adoc#_instantiation_and_subscription\" href=\"#_instantiation_and_subscription\">Instancia\u00e7\u00e3o e assinatura<\/a><\/li>\n<li><a title=\"vscode-resource:\/Users\/hod\/work\/content\/blog\/blog-source-code\/Greeley\/0052RxListener\/blogpost.adoc#_output\" href=\"#_output\">Sa\u00edda<\/a><\/li>\n<li><a title=\"vscode-resource:\/Users\/hod\/work\/content\/blog\/blog-source-code\/Greeley\/0052RxListener\/blogpost.adoc#_commentary_learning_rxjava\" href=\"#_commentary_learning_rxjava\">Coment\u00e1rios: Aprendendo RxJava<\/a><\/li>\n<li><a title=\"vscode-resource:\/Users\/hod\/work\/content\/blog\/blog-source-code\/Greeley\/0052RxListener\/blogpost.adoc#_postscript\" href=\"#_postscript\">P\u00f3s-escrito<\/a><\/li>\n<\/ul>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_introduction\">Introdu\u00e7\u00e3o<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>A programa\u00e7\u00e3o reativa e o RxJava se tornaram t\u00f3picos muito importantes, especialmente nos \u00faltimos dois anos. Tive uma amostra do RxJava ao experiment\u00e1-lo em um projeto Android h\u00e1 pouco tempo. Eu tinha um problema simples de threading, que poderia ter resolvido facilmente de outras maneiras. No entanto, como j\u00e1 havia lido sobre o RxJava, decidi experiment\u00e1-lo. Fiquei imediatamente impressionado com o fato de o c\u00f3digo ser muito mais simples e compreens\u00edvel.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Apesar desse sucesso, o RxJava tem uma certa reputa\u00e7\u00e3o de ser dif\u00edcil de aprender. Em um projeto mais recente, eu queria lidar com atualiza\u00e7\u00f5es ao vivo de um banco de dados. O banco de dados (<a title=\"https:\/\/developer.couchbase.com\/documentation\/mobile\/current\/guides\/couchbase-lite\/index.html\" href=\"https:\/\/developer.couchbase.com\/documentation\/mobile\/current\/guides\/couchbase-lite\/index.html\">Couchbase Lite<\/a>), tem um sistema baseado em retorno de chamada para monitorar altera\u00e7\u00f5es. Eu queria envolver esse retorno de chamada em uma estrutura reativa. (Isso poderia ter sido um\u00a0<a title=\"https:\/\/github.com\/ReactiveX\/RxJava\/wiki\/Observable\" href=\"https:\/\/github.com\/ReactiveX\/RxJava\/wiki\/Observable\">Observ\u00e1vel<\/a>\u00a0ou um\u00a0<a title=\"https:\/\/www.baeldung.com\/rxjava-2-flowable\" href=\"https:\/\/www.baeldung.com\/rxjava-2-flowable\">Flux\u00edvel<\/a>. Aguarde um artigo posterior que fale sobre a escolha entre eles).<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>A primeira coisa que descobri foi que n\u00e3o consegui encontrar um bom exemplo de uma vers\u00e3o geral do que eu queria. H\u00e1 um exemplo simples na se\u00e7\u00e3o\u00a0<a title=\"https:\/\/github.com\/ReactiveX\/RxJava\/wiki\/Creating-Observables#create\" href=\"https:\/\/github.com\/ReactiveX\/RxJava\/wiki\/Creating-Observables#create\">Documenta\u00e7\u00e3o do RxJava<\/a>mas ele tem algumas desvantagens que eu queria evitar. Por exemplo, no exemplo, presume-se que o objeto Event tenha um m\u00e9todo para determinar se um determinado evento \u00e9 o \u00faltimo no fluxo. Muitos retornos de chamada no Android n\u00e3o t\u00eam esse m\u00e9todo.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Embora eu tenha descoberto mais tarde um\u00a0<a title=\"https:\/\/stackoverflow.com\/a\/41870888\/968231\" href=\"https:\/\/stackoverflow.com\/a\/41870888\/968231\">Postagem no Stack Overflow<\/a>\u00a0que abrange muito bem os conceitos b\u00e1sicos, eu queria entender mais.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Uma discuss\u00e3o completa sobre os aspectos internos poderia, n\u00e3o surpreendentemente, preencher um livro. Nesta postagem, abordarei apenas o n\u00facleo. H\u00e1 um c\u00f3digo com v\u00e1rios experimentos para ajudar a entender os detalhes. Isso \u00e9 demais para um \u00fanico artigo, portanto, deixaremos isso para outra ocasi\u00e3o.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_objective\">Objetivo<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Para sermos mais expl\u00edcitos, veremos como usar uma interface de retorno de chamada de ouvinte, comum na programa\u00e7\u00e3o orientada por eventos, e transform\u00e1-la em um\u00a0<code>Observ\u00e1vel<\/code>.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Ou seja, como podemos passar de<\/p>\n<pre class=\"theme:tomorrow-night lang:java decode:true\">public interface OnItemListener&lt;T&gt; {\r\n  void onItem(T item);\r\n}<\/pre>\n<\/div>\n<div class=\"paragraph\">\n<p>para<\/p>\n<\/div>\n<pre class=\"theme:tomorrow-night lang:java decode:true\">Observable&lt;T&gt;<\/pre>\n<div class=\"paragraph\">\n<p>Android\u00a0<a title=\"https:\/\/developer.android.com\/reference\/android\/view\/View.OnClickListener\" href=\"https:\/\/developer.android.com\/reference\/android\/view\/View.OnClickListener\"><code>OnClickListener<\/code><\/a>\u00a0\u00e9 um exemplo desse tipo de API.\u00a0<code>OnClickListener<\/code>\u00a0\u00e9 uma interface com um m\u00e9todo,\u00a0<code>onClick<\/code>. Ele tem um sistema operacional Android\u00a0<code>Ver<\/code>\u00a0como par\u00e2metro. O sistema Android usa isso para fornecer fluxos de eventos, como pressionamento de bot\u00f5es e assim por diante.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_getting_started\">Primeiros passos<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>A fonte para este trabalho pode ser encontrada no GitHub\u00a0<a title=\"https:\/\/github.com\/HodGreeley\/RxJava-Listener\" href=\"https:\/\/github.com\/HodGreeley\/RxJava-Listener\">aqui<\/a>.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Nesta postagem, examinaremos apenas uma pequena parte desse c\u00f3digo. Outras partes do c\u00f3digo foram criadas para testar v\u00e1rios experimentos. Isso pode ser assunto para artigos futuros. Para isso, vamos nos concentrar apenas no t\u00f3pico central.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Para acompanhar o processo, clone o reposit\u00f3rio. O c\u00f3digo est\u00e1 configurado para ser criado pelo gradle, portanto, voc\u00ea pode execut\u00e1-lo a partir da linha de comando ou import\u00e1-lo para seu ambiente favorito.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_creating_a_source\">Criando uma fonte<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>O objetivo \u00e9 converter uma API para ouvir algum tipo de fonte de eventos. A primeira coisa que precisamos \u00e9 de um fluxo de eventos real para testar. H\u00e1 algumas fontes criadas para experimentar, portanto, come\u00e7aremos com uma classe base.<\/p>\n<\/div>\n<div class=\"sect4\">\n<h5 id=\"_listing_basicsource_java\">Listagem: BasicSource.java<\/h5>\n<\/div>\n<\/div>\n<\/div>\n<pre class=\"theme:tomorrow-night lang:java decode:true\">\/\/ File: src\/main\/java\/com\/couchbase\/rx\/BasicSource.java\r\npackage com.couchbase.rx;\r\n\r\npublic class BasicSource&lt;T&gt; {\r\n  protected volatile OnItemListener&lt;? super T&gt; listener;\r\n\r\n  public static interface OnItemListener&lt;T&gt; { void onItem(T item); }\r\n\r\n  public void setOnItemListener(OnItemListener&lt;? super T&gt; listener) { this.listener = listener; }\r\n}<\/pre>\n<div class=\"sect1\">\n<div class=\"sectionbody\">\n<div class=\"sect4\">\n<div class=\"paragraph\">\n<p>Isso define a interface e tem o campo comum e o m\u00e9todo setter necess\u00e1rios para todas as implementa\u00e7\u00f5es.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Em seguida, obtenha uma fonte que imite um fluxo ilimitado de eventos da seguinte forma.<\/p>\n<\/div>\n<\/div>\n<div class=\"sect4\">\n<h5 id=\"_listing_unboundsource_java\">Listagem: UnboundSource.java<\/h5>\n<pre class=\"theme:tomorrow-night lang:java decode:true\">\/\/ File: src\/main\/java\/com\/couchbase\/rx\/UnboundSource.java\r\npackage com.couchbase.rx;\r\n\r\nimport java.util.function.Supplier;\r\n\r\nimport static com.couchbase.Util.sleep;\r\n\r\npublic class UnboundSource&lt;T&gt; extends BasicSource&lt;T&gt; {\r\n  private Supplier&lt;T&gt; supplier;\r\n  private OnItemListener&lt;? super T&gt; current;\r\n\r\n  public UnboundSource(Supplier&lt;T&gt; supplier) {\r\n    this.supplier = supplier;\r\n  }\r\n\r\n  public void start() {\r\n    System.out.println(\"Source emitting on thread \" + Thread.currentThread().getName());\r\n\r\n    for (;;) {\r\n      System.out.println(\"Emitting item on thread \" + Thread.currentThread().getName());\r\n\r\n      current = listener;\r\n\r\n      if (null != current) current.onItem(supplier.get());\r\n\r\n      sleep(100);\r\n    }\r\n  }\r\n}<\/pre>\n<div class=\"paragraph\">\n<p>Essa vers\u00e3o gera novos itens usando um\u00a0<code>Fornecedor<\/code>\u00a0passada para o construtor. Isso apenas mostra que n\u00e3o h\u00e1 nada de especial sobre os objetos reais fornecidos, j\u00e1 que o fornecedor pode criar qualquer coisa.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Temos um m\u00e9todo para iniciar explicitamente a cria\u00e7\u00e3o de itens. Aqui, usamos um loop infinito para ger\u00e1-los indefinidamente.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>A atribui\u00e7\u00e3o de\u00a0<code>ouvinte<\/code>\u00a0para\u00a0<code>atual<\/code>\u00a0contorna uma condi\u00e7\u00e3o de corrida em que o descarte da assinatura pode ocorrer entre a verifica\u00e7\u00e3o de nulo e a invoca\u00e7\u00e3o real do\u00a0<code>onItem<\/code>\u00a0retorno de chamada.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_converting_to_an_observable\">Convers\u00e3o para um observ\u00e1vel<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>\u00d3timo, agora temos uma fonte que imita, por exemplo, uma s\u00e9rie aberta de cliques em bot\u00f5es. Em seguida, vamos criar um\u00a0<code>Observ\u00e1vel<\/code>.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Usaremos o m\u00e9todo recomendado na documenta\u00e7\u00e3o do RxJava. Ele usa a vari\u00e1vel\u00a0<code>Observ\u00e1vel.create<\/code>\u00a0em vez de subclasse\u00a0<code>Observ\u00e1vel<\/code>\u00a0diretamente. (O projeto inclui c\u00f3digo para fazer isso tamb\u00e9m, para fins de compara\u00e7\u00e3o).<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>D\u00ea uma olhada na listagem.<\/p>\n<\/div>\n<div class=\"sect4\">\n<h5 id=\"_listing_observables_java\">Listagem: Observables.java<\/h5>\n<pre class=\"theme:tomorrow-night lang:java decode:true\">\/\/ File: src\/main\/java\/com\/couchbase\/rx\/Observables.java\r\npackage com.couchbase.rx;\r\n\r\nimport io.reactivex.Observable;\r\nimport io.reactivex.ObservableOnSubscribe;\r\n\r\nimport com.couchbase.Util.ComputeFunction;\r\n\r\npublic class Observables {\r\n  public static void main(String[] args) {\r\n    UnboundSource&lt;Object&gt; source = new UnboundSource&lt;&gt;(Object::new);\r\n\r\n    ObservableOnSubscribe&lt;Object&gt; handler = emitter -&gt; {\r\n      System.out.println(\"Create on thread - \" + Thread.currentThread().getName());\r\n\r\n      source.setOnItemListener(item -&gt; {\r\n        System.out.println(\"Listen on thread - \" + Thread.currentThread().getName());\r\n\r\n        if (emitter.isDisposed()) return;\r\n        emitter.onNext(item);\r\n      });\r\n\r\n      emitter.setCancellable(() -&gt; source.setOnItemListener(null));\r\n      source.start();\r\n    };\r\n\r\n    Observable.create(handler)\r\n      .subscribe(ComputeFunction::compute, Throwable::printStackTrace,\r\n        () -&gt; System.out.println(\"Done\"), t -&gt; System.out.println(\"onSubscribe on thread \" + Thread.currentThread().getName()));\r\n  }\r\n}<\/pre>\n<div class=\"paragraph\">\n<p>Primeiro, criamos uma inst\u00e2ncia do nosso\u00a0<code>UnboundSource<\/code>.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Em seguida, criamos uma inst\u00e2ncia de\u00a0<code>ObservableOnSubscribe<\/code>\u00a0usando uma express\u00e3o lambda. O m\u00e9todo que estamos substituindo,\u00a0<code>assinar<\/code>tem um par\u00e2metro, um\u00a0<code>Emissor<\/code>\u00a0objeto.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Isso fornece a conex\u00e3o entre o retorno de chamada do ouvinte da nossa fonte e um assinante, por meio de uma segunda express\u00e3o lambda. Essa segunda express\u00e3o apenas verifica\u00a0<code>emissor.isDisposed<\/code>\u00a0para se certificar de que a assinatura ainda est\u00e1 ativa e, em seguida, empurra um item para baixo chamando\u00a0<code>emissor.onNext<\/code>. Essa \u00e9 a linha principal para a qual tudo est\u00e1 sendo constru\u00eddo.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Depois de conectar nosso retorno de chamada original, queremos oferecer uma maneira de interromper o fluxo. Usamos um\u00a0<code>Cancel\u00e1vel<\/code>\u00a0aqui para simplificar. A express\u00e3o lambda interrompe o fluxo anulando a chamada de retorno do ouvinte.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>A\u00a0<code>Descart\u00e1vel<\/code>\u00a0tamb\u00e9m funcionaria. Isso\u00a0<a title=\"https:\/\/stackoverflow.com\/a\/43283760\/968231\" href=\"https:\/\/stackoverflow.com\/a\/43283760\/968231\">Resposta do Stack Overflow<\/a>\u00a0d\u00e1 uma boa ideia da diferen\u00e7a entre eles e de como escolher qual usar.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Os descart\u00e1veis s\u00e3o a solu\u00e7\u00e3o do RxJava 2 para cancelar a assinatura de um fluxo.\u00a0<a title=\"https:\/\/blog.kaush.co\/2017\/06\/21\/rxjava-1-rxjava-2-disposing-subscriptions\/\" href=\"https:\/\/blog.kaush.co\/2017\/06\/21\/rxjava-1-rxjava-2-disposing-subscriptions\/\">Esta postagem<\/a>\u00a0por Kaushik Gopal explica alguns dos racioc\u00ednios sobre o uso de descart\u00e1veis em geral.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Com tudo interconectado, acionamos a fonte para come\u00e7ar a gerar eventos.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_instantiation_and_subscription\">Instancia\u00e7\u00e3o e assinatura<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Com nosso\u00a0<code>ObservableOnSubscribe<\/code>\u00a0em m\u00e3os, agora podemos criar nossa inst\u00e2ncia\u00a0<code>Observ\u00e1vel<\/code>\u00a0com a chamada para\u00a0<code>criar<\/code>.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>O\u00a0<code>Observ\u00e1vel<\/code>\u00a0fornece uma interface fluente com v\u00e1rios m\u00e9todos dispon\u00edveis. Assinamos o observ\u00e1vel resultante usando um m\u00e9todo que divide as fun\u00e7\u00f5es \"onXXX\" em partes individuais.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_output\">Sa\u00edda<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Se voc\u00ea executar o exemplo conforme mostrado, dever\u00e1 obter algo parecido com o seguinte resultado.<\/p>\n<pre class=\"theme:tomorrow-night lang:default decode:true\">onSubscribe on thread main\r\nCreate on thread - main\r\nSource emitting on thread main\r\nEmitting item on thread main\r\nListen on thread - main\r\nCompute: object java.lang.Object@d8355a8 on thread main\r\nEmitting item on thread main\r\nListen on thread - main\r\nCompute: object java.lang.Object@28d25987 on thread main\r\n...<\/pre>\n<\/div>\n<div class=\"paragraph\">\n<p>Tudo est\u00e1 acontecendo em s\u00e9rie no t\u00f3pico principal. N\u00e3o \u00e9 muito interessante, apesar de todo esse esfor\u00e7o. Ainda n\u00e3o aproveitamos todo o potencial do RxJava. Para quem conhece o RxJava, sabe como \u00e9 f\u00e1cil fazer com que o c\u00f3digo seja executado de forma ass\u00edncrona. Isso \u00e9 algo interessante, com peculiaridades que eu n\u00e3o esperava. Mais uma vez, algo a ser explorado em outro post.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_commentary_learning_rxjava\">Coment\u00e1rios: Aprendendo RxJava<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Quando decidi escrever esta postagem, eu queria falar sobre as coisas que aprendi ao estudar alguns aspectos internos do RxJava. No final, ficou muito grande para um artigo.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Parte do que torna o RxJava desafiador \u00e9 o grande n\u00famero de APIs, mas mesmo as b\u00e1sicas envolvem uma rede de interfaces entrela\u00e7adas.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Por exemplo, h\u00e1 apenas uma vers\u00e3o do\u00a0<code>Observ\u00e1vel.create<\/code>. \u00c9 necess\u00e1rio um\u00a0<code>ObservableOnSubscribe<\/code>\u00a0como um argumento, como vimos. Bastante simples.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Mas depois nos aprofundamos um pouco.\u00a0<code>ObservableOnSubscribe<\/code>\u00a0\u00e9 uma interface com apenas um m\u00e9todo,\u00a0<code>assinar<\/code>. Mais uma vez, simples, mas isso come\u00e7a a revelar parte do que torna complicado entender o RxJava.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Al\u00e9m disso, vemos\u00a0<code>ObservableOnSubscribe.subscribe<\/code>\u00a0fornece um\u00a0<code>Observ\u00e1velEmissor<\/code>\u00a0como um argumento. Um\u00a0<code>Observ\u00e1velEmissor<\/code>\u00a0estende um\u00a0<code>Emissor<\/code>e adiciona alguns m\u00e9todos para gerenciar um\u00a0<code>Descart\u00e1vel<\/code>. E\u00a0<code>Emissor<\/code>tem quase a mesma interface que um\u00a0<code>Observ\u00e1vel<\/code>. S\u00f3 lhe falta a\u00a0<code>onSubscribe<\/code>\u00a0m\u00e9todo.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>H\u00e1 principalmente defini\u00e7\u00f5es de interface. Ainda n\u00e3o tocamos nas implementa\u00e7\u00f5es, e estou apenas arranhando a superf\u00edcie aqui.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>O c\u00f3digo \u00e9 fascinante. Explore mais e voc\u00ea ver\u00e1 como os operadores podem modificar o que est\u00e1 acontecendo em toda uma cadeia de chamadas, como o RxJava faz o buffering, como algumas opera\u00e7\u00f5es sinalizam quantos itens devem ser transmitidos e muito mais.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Estou ansioso para explorar mais e passar adiante o que aprender.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_postscript\">P\u00f3s-escrito<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>O Couchbase \u00e9 de c\u00f3digo aberto e\u00a0<a title=\"https:\/\/www.couchbase.com\/downloads\" href=\"https:\/\/www.couchbase.com\/blog\/pt\/downloads\/\">gr\u00e1tis para experimentar<\/a>.<br \/>\n<strong>Comece a usar<\/strong>\u00a0com\u00a0<a title=\"https:\/\/www.couchbase.com\/get-started\" href=\"https:\/\/developer.couchbase.com\/tutorials\">c\u00f3digo de amostra, consultas de exemplo, tutoriais e muito mais<\/a>.<br \/>\nEncontre mais recursos em nosso\u00a0<a title=\"https:\/\/www.couchbase.com\/developers\/community\/\" href=\"https:\/\/www.couchbase.com\/blog\/pt\/developers\/community\/\">portal do desenvolvedor<\/a>.<br \/>\nSiga-nos no Twitter\u00a0<a title=\"https:\/\/twitter.com\/CouchbaseDev\" href=\"https:\/\/twitter.com\/CouchbaseDev\">@CouchbaseDev<\/a>.<br \/>\nVoc\u00ea pode postar perguntas em nosso\u00a0<a title=\"https:\/\/www.couchbase.com\/forums\/\" href=\"https:\/\/www.couchbase.com\/blog\/pt\/forums\/\">f\u00f3runs<\/a>.<br \/>\nParticipamos ativamente de\u00a0<a title=\"https:\/\/stackoverflow.com\/questions\/tagged\/couchbase\" href=\"https:\/\/stackoverflow.com\/questions\/tagged\/couchbase\">Estouro de pilha<\/a>.<br \/>\nEntre em contato comigo pelo Twitter com perguntas, coment\u00e1rios, t\u00f3picos que voc\u00ea gostaria de ver etc.\u00a0<a title=\"https:\/\/twitter.com\/HodGreeley\" href=\"https:\/\/twitter.com\/HodGreeley\">@HodGreeley<\/a><\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Logotipo do ReactiveX usado como cortesia da\u00a0<a title=\"https:\/\/reactivex.io\/\" href=\"https:\/\/reactivex.io\/\">Projetos ReactiveX<\/a>\u00a0nos termos do\u00a0<a title=\"https:\/\/creativecommons.org\/licenses\/by\/3.0\/us\/\" href=\"https:\/\/creativecommons.org\/licenses\/by\/3.0\/us\/\">Licen\u00e7a Creative Commons Attribution 3.0<\/a>.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>In this post, I\u2019ll show how to convert a callback-based listener style API to a reactive one with RxJava 2. Contents Introduction Objective Getting Started Creating a Source Listing: BasicSource.java Listing: UnboundSource.java Converting to an Observable Listing: Observables.java Instantiation and [&hellip;]<\/p>","protected":false},"author":73,"featured_media":6195,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1815,1818],"tags":[1516],"ppma_author":[9042],"class_list":["post-6194","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-best-practices-and-tutorials","category-java","tag-reactive"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.2 (Yoast SEO v26.2) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>RxJava: Wrapping Listener Callback with Observable Examples<\/title>\n<meta name=\"description\" content=\"In this post, Couchbase will show using a series of examples of how to convert a callback-based listener style API to a reactive one with RxJava 2.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/pt\/exploring-rxjava-wrapping-listener-callback\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Exploring RxJava - Wrapping a Listener Callback\" \/>\n<meta property=\"og:description\" content=\"In this post, Couchbase will show using a series of examples of how to convert a callback-based listener style API to a reactive one with RxJava 2.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/pt\/exploring-rxjava-wrapping-listener-callback\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2018-12-21T00:07:04+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-08-30T09:28:32+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/12\/ReactiveX_Logo.png\" \/>\n\t<meta property=\"og:image:width\" content=\"256\" \/>\n\t<meta property=\"og:image:height\" content=\"256\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Hod Greeley, Developer Advocate, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@HodGreeley\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Hod Greeley, Developer Advocate, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/exploring-rxjava-wrapping-listener-callback\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/exploring-rxjava-wrapping-listener-callback\/\"},\"author\":{\"name\":\"Hod Greeley, Developer Advocate, Couchbase\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/9b62593c8a13531e53d52fcd5aabbca4\"},\"headline\":\"Exploring RxJava &#8211; Wrapping a Listener Callback\",\"datePublished\":\"2018-12-21T00:07:04+00:00\",\"dateModified\":\"2024-08-30T09:28:32+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/exploring-rxjava-wrapping-listener-callback\/\"},\"wordCount\":1322,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/exploring-rxjava-wrapping-listener-callback\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/12\/ReactiveX_Logo.png\",\"keywords\":[\"Reactive\"],\"articleSection\":[\"Best Practices and Tutorials\",\"Java\"],\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/exploring-rxjava-wrapping-listener-callback\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/exploring-rxjava-wrapping-listener-callback\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/exploring-rxjava-wrapping-listener-callback\/\",\"name\":\"RxJava: Wrapping Listener Callback with Observable Examples\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/exploring-rxjava-wrapping-listener-callback\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/exploring-rxjava-wrapping-listener-callback\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/12\/ReactiveX_Logo.png\",\"datePublished\":\"2018-12-21T00:07:04+00:00\",\"dateModified\":\"2024-08-30T09:28:32+00:00\",\"description\":\"In this post, Couchbase will show using a series of examples of how to convert a callback-based listener style API to a reactive one with RxJava 2.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/exploring-rxjava-wrapping-listener-callback\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/exploring-rxjava-wrapping-listener-callback\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/exploring-rxjava-wrapping-listener-callback\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/12\/ReactiveX_Logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/12\/ReactiveX_Logo.png\",\"width\":256,\"height\":256,\"caption\":\"ReactiveX Logo\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/exploring-rxjava-wrapping-listener-callback\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Exploring RxJava &#8211; Wrapping a Listener Callback\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"pt-BR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/9b62593c8a13531e53d52fcd5aabbca4\",\"name\":\"Hod Greeley, Developer Advocate, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/21eb69cb5d4a401fb23b149e4f4e9e87\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/52d0018695c0ced0d1c68cf64a6195c81dbac03dce5983f98eb209e7c84350df?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/52d0018695c0ced0d1c68cf64a6195c81dbac03dce5983f98eb209e7c84350df?s=96&d=mm&r=g\",\"caption\":\"Hod Greeley, Developer Advocate, Couchbase\"},\"description\":\"Hod Greeley is a Developer Advocate for Couchbase, living in Silicon Valley. He has over two decades of experience as a software engineer and engineering manager. He has worked in a variety of software fields, including computational physics and chemistry, computer and network security, finance, and mobile. Prior to joining Couchbase in 2016, Hod led developer relations for mobile at Samsung. Hod holds a Ph.D. in chemical physics from Columbia University.\",\"sameAs\":[\"https:\/\/hod.greeley.org\/blog\",\"https:\/\/x.com\/HodGreeley\"],\"url\":\"https:\/\/www.couchbase.com\/blog\/pt\/author\/hod-greeley\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"RxJava: Wrapping Listener Callback with Observable Examples","description":"Nesta postagem, o Couchbase mostrar\u00e1, por meio de uma s\u00e9rie de exemplos, como converter uma API de estilo de ouvinte baseada em callback em uma API reativa com o RxJava 2.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/pt\/exploring-rxjava-wrapping-listener-callback\/","og_locale":"pt_BR","og_type":"article","og_title":"Exploring RxJava - Wrapping a Listener Callback","og_description":"In this post, Couchbase will show using a series of examples of how to convert a callback-based listener style API to a reactive one with RxJava 2.","og_url":"https:\/\/www.couchbase.com\/blog\/pt\/exploring-rxjava-wrapping-listener-callback\/","og_site_name":"The Couchbase Blog","article_published_time":"2018-12-21T00:07:04+00:00","article_modified_time":"2024-08-30T09:28:32+00:00","og_image":[{"width":256,"height":256,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/12\/ReactiveX_Logo.png","type":"image\/png"}],"author":"Hod Greeley, Developer Advocate, Couchbase","twitter_card":"summary_large_image","twitter_creator":"@HodGreeley","twitter_misc":{"Written by":"Hod Greeley, Developer Advocate, Couchbase","Est. reading time":"7 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/exploring-rxjava-wrapping-listener-callback\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/exploring-rxjava-wrapping-listener-callback\/"},"author":{"name":"Hod Greeley, Developer Advocate, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/9b62593c8a13531e53d52fcd5aabbca4"},"headline":"Exploring RxJava &#8211; Wrapping a Listener Callback","datePublished":"2018-12-21T00:07:04+00:00","dateModified":"2024-08-30T09:28:32+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/exploring-rxjava-wrapping-listener-callback\/"},"wordCount":1322,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/exploring-rxjava-wrapping-listener-callback\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/12\/ReactiveX_Logo.png","keywords":["Reactive"],"articleSection":["Best Practices and Tutorials","Java"],"inLanguage":"pt-BR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/exploring-rxjava-wrapping-listener-callback\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/exploring-rxjava-wrapping-listener-callback\/","url":"https:\/\/www.couchbase.com\/blog\/exploring-rxjava-wrapping-listener-callback\/","name":"RxJava: Wrapping Listener Callback with Observable Examples","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/exploring-rxjava-wrapping-listener-callback\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/exploring-rxjava-wrapping-listener-callback\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/12\/ReactiveX_Logo.png","datePublished":"2018-12-21T00:07:04+00:00","dateModified":"2024-08-30T09:28:32+00:00","description":"Nesta postagem, o Couchbase mostrar\u00e1, por meio de uma s\u00e9rie de exemplos, como converter uma API de estilo de ouvinte baseada em callback em uma API reativa com o RxJava 2.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/exploring-rxjava-wrapping-listener-callback\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/exploring-rxjava-wrapping-listener-callback\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/exploring-rxjava-wrapping-listener-callback\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/12\/ReactiveX_Logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/12\/ReactiveX_Logo.png","width":256,"height":256,"caption":"ReactiveX Logo"},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/exploring-rxjava-wrapping-listener-callback\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Exploring RxJava &#8211; Wrapping a Listener Callback"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"Blog do Couchbase","description":"Couchbase, o banco de dados NoSQL","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"pt-BR"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"Blog do Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/9b62593c8a13531e53d52fcd5aabbca4","name":"Hod Greeley, Advogado do desenvolvedor, Couchbase","image":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/21eb69cb5d4a401fb23b149e4f4e9e87","url":"https:\/\/secure.gravatar.com\/avatar\/52d0018695c0ced0d1c68cf64a6195c81dbac03dce5983f98eb209e7c84350df?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/52d0018695c0ced0d1c68cf64a6195c81dbac03dce5983f98eb209e7c84350df?s=96&d=mm&r=g","caption":"Hod Greeley, Developer Advocate, Couchbase"},"description":"Hod Greeley \u00e9 um defensor dos desenvolvedores da Couchbase e mora no Vale do Sil\u00edcio. Ele tem mais de duas d\u00e9cadas de experi\u00eancia como engenheiro de software e gerente de engenharia. Trabalhou em diversas \u00e1reas de software, incluindo f\u00edsica e qu\u00edmica computacional, seguran\u00e7a de computadores e redes, finan\u00e7as e dispositivos m\u00f3veis. Antes de ingressar na Couchbase em 2016, Hod liderou as rela\u00e7\u00f5es com desenvolvedores para dispositivos m\u00f3veis na Samsung. Hod \u00e9 Ph.D. em f\u00edsica qu\u00edmica pela Universidade de Columbia.","sameAs":["https:\/\/hod.greeley.org\/blog","https:\/\/x.com\/HodGreeley"],"url":"https:\/\/www.couchbase.com\/blog\/pt\/author\/hod-greeley\/"}]}},"authors":[{"term_id":9042,"user_id":73,"is_guest":0,"slug":"hod-greeley","display_name":"Hod Greeley, Developer Advocate, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/52d0018695c0ced0d1c68cf64a6195c81dbac03dce5983f98eb209e7c84350df?s=96&d=mm&r=g","author_category":"","last_name":"Greeley","first_name":"Hod","job_title":"","user_url":"https:\/\/hod.greeley.org\/blog","description":"Hod Greeley \u00e9 um defensor dos desenvolvedores da Couchbase e mora no Vale do Sil\u00edcio. Ele tem mais de duas d\u00e9cadas de experi\u00eancia como engenheiro de software e gerente de engenharia. Trabalhou em diversas \u00e1reas de software, incluindo f\u00edsica e qu\u00edmica computacional, seguran\u00e7a de computadores e redes, finan\u00e7as e dispositivos m\u00f3veis. Antes de ingressar na Couchbase em 2016, Hod liderou as rela\u00e7\u00f5es com desenvolvedores para dispositivos m\u00f3veis na Samsung. Hod \u00e9 Ph.D. em f\u00edsica qu\u00edmica pela Universidade de Columbia."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/6194","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/users\/73"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/comments?post=6194"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/6194\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media\/6195"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media?parent=6194"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=6194"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=6194"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=6194"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}