{"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\/es\/exploring-rxjava-wrapping-listener-callback\/","title":{"rendered":"Explorando RxJava - Envolver una llamada de retorno a un receptor"},"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\/es\/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>En este post, voy a mostrar c\u00f3mo convertir una API basada en callback estilo listener a una reactiva con RxJava 2.<\/p>\n<\/div>\n<div id=\"toc\" class=\"toc\">\n<div id=\"toctitle\" class=\"title\">Contenido<\/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\">Introducci\u00f3n<\/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\">Primeros pasos<\/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\">Creaci\u00f3n de una fuente<\/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\">Listado: 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\">Listado: 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\">Conversi\u00f3n a observable<\/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\">Listado: 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\">Instanciaci\u00f3n y suscripci\u00f3n<\/a><\/li>\n<li><a title=\"vscode-resource:\/Users\/hod\/work\/content\/blog\/blog-source-code\/Greeley\/0052RxListener\/blogpost.adoc#_output\" href=\"#_output\">Salida<\/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\">Comentarios: Aprender RxJava<\/a><\/li>\n<li><a title=\"vscode-resource:\/Users\/hod\/work\/content\/blog\/blog-source-code\/Greeley\/0052RxListener\/blogpost.adoc#_postscript\" href=\"#_postscript\">Posdata<\/a><\/li>\n<\/ul>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_introduction\">Introducci\u00f3n<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>La programaci\u00f3n reactiva y RxJava se han convertido en temas bastante candentes, especialmente en los \u00faltimos dos a\u00f1os. Hace un tiempo prob\u00e9 RxJava en un proyecto Android. Ten\u00eda un simple problema de hilos, que podr\u00eda haber resuelto f\u00e1cilmente de otras maneras. Sin embargo, como hab\u00eda estado leyendo sobre RxJava, decid\u00ed probarlo. Inmediatamente me impresion\u00f3 lo mucho m\u00e1s sencillo y comprensible que era el c\u00f3digo.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>A pesar de ese \u00e9xito, RxJava tiene fama de ser dif\u00edcil de aprender. En un proyecto m\u00e1s reciente, quer\u00eda manejar actualizaciones en vivo de una base de datos. La base de datos (<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>), tiene un sistema basado en callbacks para monitorizar los cambios. Yo quer\u00eda envolver ese callback en una estructura reactiva. (Esto podr\u00eda haber sido un\u00a0<a title=\"https:\/\/github.com\/ReactiveX\/RxJava\/wiki\/Observable\" href=\"https:\/\/github.com\/ReactiveX\/RxJava\/wiki\/Observable\">Observable<\/a>\u00a0o un\u00a0<a title=\"https:\/\/www.baeldung.com\/rxjava-2-flowable\" href=\"https:\/\/www.baeldung.com\/rxjava-2-flowable\">Fluido<\/a>. En un pr\u00f3ximo art\u00edculo hablaremos de c\u00f3mo elegir entre ellos).<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Lo primero que descubr\u00ed fue que no pod\u00eda encontrar un buen ejemplo de una versi\u00f3n general de lo que quer\u00eda. Hay un ejemplo sencillo en el\u00a0<a title=\"https:\/\/github.com\/ReactiveX\/RxJava\/wiki\/Creating-Observables#create\" href=\"https:\/\/github.com\/ReactiveX\/RxJava\/wiki\/Creating-Observables#create\">Documentaci\u00f3n de RxJava<\/a>pero tiene algunos inconvenientes que quer\u00eda evitar. Por ejemplo, en el ejemplo, se asume que el objeto Evento tiene un m\u00e9todo para determinar si un evento dado es el \u00faltimo en el flujo. Muchos callbacks en Android no tienen tal m\u00e9todo.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Aunque m\u00e1s tarde descubr\u00ed una\u00a0<a title=\"https:\/\/stackoverflow.com\/a\/41870888\/968231\" href=\"https:\/\/stackoverflow.com\/a\/41870888\/968231\">Stack Overflow post<\/a>\u00a0que cubre lo b\u00e1sico bastante bien, quer\u00eda entender m\u00e1s.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>No es de extra\u00f1ar que un an\u00e1lisis completo de su funcionamiento interno pudiera llenar un libro. En este post me limitar\u00e9 a cubrir el n\u00facleo. Hay c\u00f3digo con varios experimentos para ayudar a entender los detalles. Eso es demasiado para un art\u00edculo, as\u00ed que lo dejaremos para otro momento.<\/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 ser m\u00e1s expl\u00edcitos, veremos c\u00f3mo tomar una interfaz de devoluci\u00f3n de llamada de oyente, com\u00fan en la programaci\u00f3n basada en eventos, y envolverla en un archivo\u00a0<code>Observable<\/code>.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Es decir, \u00bfc\u00f3mo pasamos de<\/p>\n<pre class=\"theme:tomorrow-night lang:java decode:true\">public interface OnItemListener {\r\n  void onItem(T item);\r\n}<\/pre>\n<\/div>\n<div class=\"paragraph\">\n<p>a<\/p>\n<\/div>\n<pre class=\"theme:tomorrow-night lang:java decode:true\">Observable<\/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>\u00a0es un ejemplo de este tipo de API.\u00a0<code>OnClickListener<\/code>\u00a0es una interfaz con un m\u00e9todo,\u00a0<code>onClick<\/code>. Dispone de un Android\u00a0<code>Ver<\/code>\u00a0como par\u00e1metro. El sistema Android utiliza esto para entregar flujos de eventos como pulsaciones de botones, etc.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_getting_started\">Primeros pasos<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>La fuente de este trabajo se encuentra en GitHub\u00a0<a title=\"https:\/\/github.com\/HodGreeley\/RxJava-Listener\" href=\"https:\/\/github.com\/HodGreeley\/RxJava-Listener\">aqu\u00ed<\/a>.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>En este post s\u00f3lo veremos una peque\u00f1a parte de ese c\u00f3digo. Otras partes del c\u00f3digo est\u00e1n dise\u00f1adas para probar varios experimentos. Esos pueden ser algo para futuros art\u00edculos. Por ahora, s\u00f3lo nos centraremos en el tema central.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Para seguirlo, clona el repositorio. El c\u00f3digo est\u00e1 configurado para ser construido por gradle, por lo que puede ejecutarlo desde la l\u00ednea de comandos o importarlo en su entorno favorito.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_creating_a_source\">Creaci\u00f3n de una fuente<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>El objetivo es convertir una API para escuchar alg\u00fan tipo de fuente de eventos. Lo primero que necesitamos es un flujo de eventos real con el que probar. Hay algunas fuentes construidas para experimentar, as\u00ed que vamos a empezar con una clase base.<\/p>\n<\/div>\n<div class=\"sect4\">\n<h5 id=\"_listing_basicsource_java\">Listado: BasicSource.java<\/h5>\n<\/div>\n<\/div>\n<\/div>\n<pre class=\"theme:tomorrow-night lang:java decode:true\">\/\/ Archivo: src\/main\/java\/com\/couchbase\/rx\/BasicSource.java\r\npaquete com.couchbase.rx;\r\n\r\npublic clase BasicSource {\r\n  protected volatile OnItemListener listener;\r\n\r\n  public static interface OnItemListener { void onItem(T item); }\r\n\r\n  public void setOnItemListener(OnItemListener 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>Define la interfaz y tiene el campo com\u00fan y el m\u00e9todo setter que necesitan todas las implementaciones.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>A continuaci\u00f3n, deduzca una fuente que imite un flujo ilimitado de eventos de la siguiente manera.<\/p>\n<\/div>\n<\/div>\n<div class=\"sect4\">\n<h5 id=\"_listing_unboundsource_java\">Listado: UnboundSource.java<\/h5>\n<pre class=\"theme:tomorrow-night lang:java decode:true\">\/\/ Archivo: src\/main\/java\/com\/couchbase\/rx\/UnboundSource.java\r\npaquete com.couchbase.rx;\r\n\r\nimportar java.util.function.Supplier;\r\n\r\nimport static com.couchbase.Util.sleep;\r\n\r\npublic clase UnboundSource extends BasicSource {\r\n  private Proveedor supplier;\r\n  private OnItemListener current;\r\n\r\n  public UnboundSource(Proveedor supplier) {\r\n    this.supplier = supplier;\r\n  }\r\n\r\n  public void start() {\r\n    System.out.println(\"Fuente emitiendo en hilo \" + Thread.currentThread().getName());\r\n\r\n    for (;;) {\r\n      System.out.println(\"Fuente emitiendo en hilo \" + Thread.currentThread().getName());\r\n\r\n      current = listener;\r\n\r\n      if (null != current) current.onItem(proveedor.get());\r\n\r\n      sleep(100);\r\n    }\r\n  }\r\n}<\/pre>\n<div class=\"paragraph\">\n<p>Esta versi\u00f3n genera nuevos elementos utilizando un\u00a0<code>Proveedor<\/code>\u00a0pasada al constructor. Esto s\u00f3lo muestra que no hay nada especial acerca de los objetos reales alimentados, ya que el proveedor podr\u00eda crear cualquier cosa.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Tenemos un m\u00e9todo para empezar a crear elementos expl\u00edcitamente. Aqu\u00ed usamos un bucle infinito para generarlos indefinidamente.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>La asignaci\u00f3n de\u00a0<code>oyente<\/code>\u00a0a\u00a0<code>actual<\/code>\u00a0soluciona una condici\u00f3n de carrera en la que la eliminaci\u00f3n de la suscripci\u00f3n puede producirse entre la comprobaci\u00f3n de null y la invocaci\u00f3n real del m\u00e9todo\u00a0<code>onItem<\/code>\u00a0devoluci\u00f3n de llamada.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_converting_to_an_observable\">Conversi\u00f3n a observable<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Genial, ahora tenemos una fuente que imita, digamos, una serie abierta de pulsaciones de bot\u00f3n. A continuaci\u00f3n, vamos a crear un\u00a0<code>Observable<\/code>.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Utilizaremos el m\u00e9todo recomendado en la documentaci\u00f3n de RxJava. \u00c9ste utiliza el m\u00e9todo\u00a0<code>Observable.create<\/code>\u00a0en lugar de subclasificar\u00a0<code>Observable<\/code>\u00a0directamente. (El proyecto incluye tambi\u00e9n c\u00f3digo para hacer esto \u00faltimo, a modo de comparaci\u00f3n).<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Echa un vistazo al listado.<\/p>\n<\/div>\n<div class=\"sect4\">\n<h5 id=\"_listing_observables_java\">Listado: Observables.java<\/h5>\n<pre class=\"theme:tomorrow-night lang:java decode:true\">\/\/ Archivo: src\/main\/java\/com\/couchbase\/rx\/Observables.java\r\npaquete 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<object> source = new UnboundSource(Object::new);\r\n\r\n    ObservableOnSubscribe<object> handler = emisor -&gt; {\r\n      System.out.println(\"Crear en hilo - \" + Thread.currentThread().getName());\r\n\r\n      source.setOnItemListener(item -&gt; {\r\n        System.out.println(\"Escucha en hilo - \" + Thread.currentThread().getName());\r\n\r\n        if (emitter.isDisposed()) return;\r\n        emisor.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(\"Hecho\"), t -&gt; System.out.println(\"onSubscribe on thread \" + Thread.currentThread().getName()));\r\n  }\r\n}<\/pre>\n<div class=\"paragraph\">\n<p>En primer lugar, creamos una instancia de nuestro\u00a0<code>Fuente no vinculante<\/code>.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>A continuaci\u00f3n, creamos una instancia de\u00a0<code>ObservableOnSubscribe<\/code>\u00a0utilizando una expresi\u00f3n lambda. El m\u00e9todo que estamos sobrescribiendo,\u00a0<code>suscr\u00edbase a<\/code>tiene un par\u00e1metro, un\u00a0<code>Emisor<\/code>\u00a0objeto.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Esto proporciona la conexi\u00f3n entre la llamada de retorno del oyente de nuestra fuente y un suscriptor, a trav\u00e9s de una segunda expresi\u00f3n lambda. Esta segunda expresi\u00f3n s\u00f3lo comprueba\u00a0<code>emisor.isDisposed<\/code>\u00a0para asegurarse de que la suscripci\u00f3n sigue activa y, a continuaci\u00f3n, empuja un elemento hacia abajo llamando a\u00a0<code>emisor.onSiguiente<\/code>. Esa es la l\u00ednea clave que esto ha estado construyendo.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Despu\u00e9s de haber conectado nuestra llamada de retorno original, queremos proporcionar una forma de detener el flujo. Para ello utilizamos un\u00a0<code>Cancelable<\/code>\u00a0aqu\u00ed por simplicidad. La expresi\u00f3n lambda rompe el flujo anulando la llamada de retorno del oyente.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>A\u00a0<code>Desechable<\/code>\u00a0tambi\u00e9n funcionar\u00eda. Este\u00a0<a title=\"https:\/\/stackoverflow.com\/a\/43283760\/968231\" href=\"https:\/\/stackoverflow.com\/a\/43283760\/968231\">Respuesta de Stack Overflow<\/a>\u00a0da una buena idea de la diferencia entre ellos y de c\u00f3mo elegir cu\u00e1l utilizar.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Los desechables son la soluci\u00f3n de RxJava 2 para darse de baja de un flujo.\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\/\">Este puesto<\/a>\u00a0de Kaushik Gopal explica algunos de los razonamientos en torno al uso de productos desechables en general.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Con todo interconectado, encendemos la fuente para empezar a generar eventos.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_instantiation_and_subscription\">Instanciaci\u00f3n y suscripci\u00f3n<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Con nuestro\u00a0<code>ObservableOnSubscribe<\/code>\u00a0ya podemos crear nuestro\u00a0<code>Observable<\/code>\u00a0con la llamada a\u00a0<code>crear<\/code>.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>En\u00a0<code>Observable<\/code>\u00a0proporciona una interfaz fluida con bastantes m\u00e9todos disponibles. Nos suscribimos al observable resultante utilizando un m\u00e9todo que descompone las funciones 'onXXX' en piezas individuales.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_output\">Salida<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Si ejecuta el ejemplo como se muestra, deber\u00eda obtener algo parecido a la siguiente salida.<\/p>\n<pre class=\"theme:tomorrow-night lang:default decode:true\">onSubscribe en el hilo principal\r\nCrear en hilo - main\r\nEmisi\u00f3n de fuente en el subproceso principal\r\nEmisi\u00f3n de elemento en el subproceso principal\r\nEscuchar en hilo - main\r\nComputa: objeto java.lang.Object@d8355a8 en hilo main\r\nEmisi\u00f3n de elemento en el subproceso principal\r\nEscucha en hilo - main\r\nComputa: objeto java.lang.Object@28d25987 en hilo main\r\n...<\/pre>\n<\/div>\n<div class=\"paragraph\">\n<p>Todo est\u00e1 sucediendo en serie en el hilo principal. No es super interesante, por todo ese esfuerzo. A\u00fan no hemos aprovechado toda la potencia de RxJava. Para aquellos familiarizados con RxJava, sabr\u00e1n lo f\u00e1cil que es hacer que el c\u00f3digo se ejecute de forma as\u00edncrona. Eso es algo interesante con peculiaridades que no esperaba. De nuevo, algo a explorar en otro post.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_commentary_learning_rxjava\">Comentarios: Aprender RxJava<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Cuando originalmente decid\u00ed escribir este post, quer\u00eda hablar de las cosas que aprend\u00ed mientras estudiaba algunos de los aspectos internos de RxJava. Al final, se convirti\u00f3 en demasiado para un art\u00edculo.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Parte de lo que hace que RxJava sea un reto es el gran n\u00famero de API, pero incluso las m\u00e1s b\u00e1sicas implican una red de interfaces entrelazadas.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Por ejemplo, s\u00f3lo hay una versi\u00f3n de\u00a0<code>Observable.create<\/code>. Se necesita un\u00a0<code>ObservableOnSubscribe<\/code>\u00a0instancia como argumento, como hemos visto. Bastante simple.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Pero luego profundizamos un poco.\u00a0<code>ObservableOnSubscribe<\/code>\u00a0es una interfaz con un solo m\u00e9todo,\u00a0<code>suscr\u00edbase a<\/code>. De nuevo, simple, pero esto empieza a revelar parte de lo que hace que entender RxJava sea complicado.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Yendo m\u00e1s all\u00e1, vemos\u00a0<code>ObservableOnSubscribe.subscribe<\/code>\u00a0suministra un\u00a0<code>ObservableEmitter<\/code>\u00a0como argumento. Un\u00a0<code>ObservableEmitter<\/code>\u00a0ampl\u00eda un\u00a0<code>Emisor<\/code>y a\u00f1ade algunos m\u00e9todos para gestionar un\u00a0<code>Desechable<\/code>. Un\u00a0<code>Emisor<\/code>resulta que tiene casi la misma interfaz que un\u00a0<code>Observable<\/code>. S\u00f3lo le falta el\u00a0<code>onSubscribe<\/code>\u00a0m\u00e9todo.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>La mayor\u00eda son definiciones de interfaces. No hemos tocado las implementaciones, y s\u00f3lo estoy ara\u00f1ando la superficie aqu\u00ed.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>El c\u00f3digo es fascinante. Si exploras m\u00e1s, descubrir\u00e1s c\u00f3mo los operadores pueden modificar lo que ocurre en toda una cadena de llamadas, c\u00f3mo RxJava almacena en b\u00fafer, c\u00f3mo algunas operaciones indican cu\u00e1ntos elementos deben pasarse y mucho m\u00e1s.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Estoy deseando seguir explorando y transmitir lo que aprenda.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_postscript\">Posdata<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Couchbase es de c\u00f3digo abierto y\u00a0<a title=\"https:\/\/www.couchbase.com\/downloads\" href=\"https:\/\/www.couchbase.com\/blog\/es\/downloads\/\">probar gratis<\/a>.<br \/>\n<strong>Empezar<\/strong>\u00a0con\u00a0<a title=\"https:\/\/www.couchbase.com\/get-started\" href=\"https:\/\/developer.couchbase.com\/tutorials\">c\u00f3digo de ejemplo, consultas de ejemplo, tutoriales y mucho m\u00e1s<\/a>.<br \/>\nM\u00e1s recursos en nuestra\u00a0<a title=\"https:\/\/www.couchbase.com\/developers\/community\/\" href=\"https:\/\/www.couchbase.com\/blog\/es\/developers\/community\/\">portal para desarrolladores<\/a>.<br \/>\nS\u00edguenos en Twitter\u00a0<a title=\"https:\/\/twitter.com\/CouchbaseDev\" href=\"https:\/\/twitter.com\/CouchbaseDev\">@CouchbaseDev<\/a>.<br \/>\nPuede enviar preguntas a nuestro\u00a0<a title=\"https:\/\/www.couchbase.com\/forums\/\" href=\"https:\/\/www.couchbase.com\/blog\/es\/forums\/\">foros<\/a>.<br \/>\nParticipamos activamente en\u00a0<a title=\"https:\/\/stackoverflow.com\/questions\/tagged\/couchbase\" href=\"https:\/\/stackoverflow.com\/questions\/tagged\/couchbase\">Stack Overflow<\/a>.<br \/>\nEnv\u00edame tus preguntas, comentarios, temas que te gustar\u00eda ver, etc. a Twitter.\u00a0<a title=\"https:\/\/twitter.com\/HodGreeley\" href=\"https:\/\/twitter.com\/HodGreeley\">@HodGreeley<\/a><\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Logotipo de ReactiveX utilizado por cortes\u00eda del\u00a0<a title=\"https:\/\/reactivex.io\/\" href=\"https:\/\/reactivex.io\/\">Proyectos ReactiveX<\/a>\u00a0en virtud del\u00a0<a title=\"https:\/\/creativecommons.org\/licenses\/by\/3.0\/us\/\" href=\"https:\/\/creativecommons.org\/licenses\/by\/3.0\/us\/\">Licencia Creative Commons Atribuci\u00f3n 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.0 (Yoast SEO v26.0) - 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\/es\/exploring-rxjava-wrapping-listener-callback\/\" \/>\n<meta property=\"og:locale\" content=\"es_MX\" \/>\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\/es\/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\":\"es\",\"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\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/exploring-rxjava-wrapping-listener-callback\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@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\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@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\":\"es\",\"@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\/es\/author\/hod-greeley\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"RxJava: Wrapping Listener Callback with Observable Examples","description":"En este post, Couchbase mostrar\u00e1 mediante una serie de ejemplos c\u00f3mo convertir una API de estilo listener basada en callbacks a una reactiva con 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\/es\/exploring-rxjava-wrapping-listener-callback\/","og_locale":"es_MX","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\/es\/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":"es","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":"En este post, Couchbase mostrar\u00e1 mediante una serie de ejemplos c\u00f3mo convertir una API de estilo listener basada en callbacks a una reactiva con RxJava 2.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/exploring-rxjava-wrapping-listener-callback\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/exploring-rxjava-wrapping-listener-callback\/"]}]},{"@type":"ImageObject","inLanguage":"es","@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":"El blog de Couchbase","description":"Couchbase, la base de datos 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":"es"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"El blog de Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"es","@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, Defensor del Desarrollador, Couchbase","image":{"@type":"ImageObject","inLanguage":"es","@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 es desarrollador de Couchbase y vive en Silicon Valley. Tiene m\u00e1s de dos d\u00e9cadas de experiencia como ingeniero de software y director de ingenier\u00eda. Ha trabajado en una variedad de campos de software, incluyendo f\u00edsica computacional y qu\u00edmica, seguridad inform\u00e1tica y de redes, finanzas y m\u00f3viles. Antes de unirse a Couchbase en 2016, Hod dirigi\u00f3 las relaciones con desarrolladores para m\u00f3viles en Samsung. Hod es doctor en f\u00edsica qu\u00edmica por la Universidad de Columbia.","sameAs":["https:\/\/hod.greeley.org\/blog","https:\/\/x.com\/HodGreeley"],"url":"https:\/\/www.couchbase.com\/blog\/es\/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 es desarrollador de Couchbase y vive en Silicon Valley. Tiene m\u00e1s de dos d\u00e9cadas de experiencia como ingeniero de software y director de ingenier\u00eda. Ha trabajado en una variedad de campos de software, incluyendo f\u00edsica computacional y qu\u00edmica, seguridad inform\u00e1tica y de redes, finanzas y m\u00f3viles. Antes de unirse a Couchbase en 2016, Hod dirigi\u00f3 las relaciones con desarrolladores para m\u00f3viles en Samsung. Hod es doctor en f\u00edsica qu\u00edmica por la Universidad de Columbia."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/6194","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/users\/73"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/comments?post=6194"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/6194\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media\/6195"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media?parent=6194"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/categories?post=6194"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/tags?post=6194"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/ppma_author?post=6194"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}