1. Retrasar la acción de ejecución
Se puede implementar utilizando el método de mapa de temporizador+. El código es el siguiente:
Observable.timer (5, timeUnit.milliseConds) .map (valor-> {return dosomthing ();}). Suscríbete (system.out :: println); } 2. Retrasar el resultado de envío
Este escenario requiere que la acción de generar datos se ejecute de inmediato, pero el resultado se retrasa en el envío. Esto es diferente del escenario anterior.
Este escenario se puede implementar utilizando Observable.zip .
El operador ZIP combina los datos transmitidos por múltiples observables en orden, cada datos solo se puede combinar una vez, y todos están ordenados. El número de datos combinados finales está determinado por el observable, que transmite los menos datos.
Para los datos en la misma ubicación de cada observable, debe esperarse unos a otros. Es decir, después de generar los datos en la primera ubicación del primer observable, debe esperar a que se generen los datos en la primera ubicación de la segunda observable, y después de generar los datos en la misma ubicación de cada observable, puede combinar de acuerdo con las reglas especificadas. Esto es realmente lo que queremos usar.
Hay muchos tipos de declaraciones en ZIP, pero es más o menos lo mismo, que es pasar en varios observables, luego especificar una regla para procesar los datos en la ubicación correspondiente de cada observable y generar un nuevo datos. Aquí está uno de los más simples:
Public Static <t1, t2, r> observable <r> zip (observable <? extiende t1> o1, observable <? extiende t2> o2, func2 final <? super t1, "super t2," extiende r> zipfunction);
Los resultados de ejecución de Push and SEND usando ZIP son los siguientes:
Observable.zip (observable.timer (5, timeUnit.milliseConds), observable.just (dosomething ()), (x, y)-> y) .subscribe (system.out :: println));
3. Use Diferte para realizar ciertas acciones en el hilo especificado
Como en el siguiente código, aunque especificamos el método de ejecución del hilo, la función doSomething() todavía se ejecuta en el hilo llamado por el código actual.
Observable.just (dosomthing ()) .subscriteon (schedulers.io ()) .observeon (schedulers.computation ()) .subscribe (v-> utils.printlnwiththread (v.tostring ()););
Por lo general, utilizamos los siguientes métodos para lograr nuestro objetivo:
Observable.create (s-> {s.onnext (dosomthingthet ());}) .subscriteon (schedulers.io ()) .observeon (schedulers.Computation ()) .subscribe (v-> {utils.printlnwithththread (v.ToString ());});Pero, de hecho, podemos lograr el mismo objetivo utilizando diferencias.
Sobre diferir
El operador de diferencias es lo mismo que Crear, justo, de y otros operadores. Crea operadores de clase, pero todos los datos relacionados con este operador entran en vigencia solo si se suscribe.
declaración:
Pública estática <t> observable <t> diferir (func0 <observable <t>> observableFactory);
El observable en Func0 de Difer se crea solo cuando se suscribe.
efecto:
No cree el observable hasta que un observador se suscribe; Cree un nuevo observable en cada suscripción.
En otras palabras, se crea observable al suscribirse.
El problema anterior se implementa con Difer:
Observable.defer (()-> observable.just (dosomthing ())) .subscriteon (schedulers.io ()) .observeon (schedulers.Computation ()) .subscribe (v-> {utils.printlnwithththread (v.Tostring ());}); 4. No rompa la estructura de la cadena usando composición
A menudo vemos el siguiente código:
Observable.just (dosomthing ()) .subScribeon (schedulers.io ()) .observeon (schedulers.Computation ()) .subscribe (V-> {utils.printlnwiththread (v.ToString ()); En el código anterior, subscribeOn(xxx).observeOn(xxx) puede ser el mismo en muchos lugares. Si planeamos implementarlo en un lugar determinado, podemos escribirlo así:
PRIVADO ESTÁTICO <T> observable <T> Aplicar Schedulers (observable <t> observable) {return observable.subScribeon (schedulers.io ()) .observeon (schedulers.computation ()); }Pero cada vez que necesitemos llamar al método anterior, será aproximadamente como lo siguiente, y lo más externo es una función, que es equivalente a romper la estructura del enlace:
ApplySchedulers (Observable.From (Somesource) .map (new Func1 <data, data> () {@Override Public Data Call (Data Data) {return Manipulate (data);}})) .subscribe (new Action1 <s data> () {@Override public void llame (datos de datos) {Dosming);}});El operador de composición se puede utilizar para lograr el propósito de no romper la estructura del enlace.
La declaración de composición es la siguiente:
composición pública observable (transformador <? Super t, "extiende r> transformador);
Su parámetro entrante es una interfaz de transformador y la salida es una observable. El transformador es en realidad un Func1<Observable<T> , Observable<R>> , en otras palabras: un tipo de observable puede convertirse en otro tipo de observable.
En pocas palabras, la composición puede convertir el observable original en otro observable a través del método de conversión especificado (transformador de parámetros de entrada).
A través de la composición, use el siguiente método para especificar el método de subproceso:
Private static <t> transformer <t, t> ApplySchedulers () {return new Transformer <t, t> () {@Override public observable <t> call (observable <t> observable) {return observable.subscriteon (Prochedulers.io ()) .Observeon (programadores.computation ()); }}; } Observable.just (dosomething ()). Compose (ApplySchedulers ()) .SubScribe (V-> {utils.printlnwithThread (V.ToString ());});La función AplicatsSchedulers se puede simplificar más utilizando expresiones Lambda a lo siguiente:
static privado <t> transformador <t, t> ApplySchedulers () {return observable-> observable.subscribeon (schedulers.io ()) .observeon (schedulers.computation ()); } 5. Use diferentes resultados de ejecución según la prioridad
El título anterior probablemente no expresó el escenario que quería expresar claramente. De hecho, el escenario que quiero expresar es similar al escenario habitual de obtener datos de red: si hay un caché, se obtendrá de la memoria caché, y si no hay NO, se obtendrá de la red.
Aquí se requiere que si hay un caché, no se realizará la acción de obtener datos de la red.
Esto se puede implementar utilizando concat+primero.
Concat fusiona varios observables en uno observable y devuelve el final observable final. Y esos datos son como ser enviados desde un observable. Los parámetros pueden ser múltiples observables o iteradores que contienen Observalbe.
Los datos en el nuevo observable se organizan en el orden del observable en el concat original, es decir, los datos en el nuevo resultado se clasifican en el orden original.
La siguiente es la implementación de los requisitos anteriores:
Observable.concat (getDataFromCache (), getDataFromNetwork ()). Primero () .SubScribe (V-> System.out.println ("Resultado:"+V)); // Obtenga datos de Cache Private static observable <String> getDataFromCache () {return observable.create (s -> {// DoSomething para obtener datos int value = new Random (). NextInt (); valor = valor%2; if (valor! = 0) {s.onNext ("Data de cache:"+valor); // create data} //sh érror(neerreRror(neRor(Newer (ninguno "))); s.onCompleted (); } // Obtener datos de la red privada observable static <string> getDataFromNetwork () {return observable.create (s -> {for (int i = 0; i <10; i ++) {utils.println ("obs2"+i); s.onnext ("data de la red:"+i); // generar datos} s.oncompleted (););});});}; }En la implementación anterior, si GetDataFromCache tiene datos, el código aquí en GetDataFromNetwork no se ejecutará, que es exactamente lo que queremos.
Hay varias implementaciones anteriores que necesitan atención:
1. Es posible que los datos no se puedan obtener de ambos lugares. En este escenario, usar primero lanzará una excepción NosuchelementException. Si este escenario es el caso, debe reemplazar el primero anterior con FirstorDefault.
2. En getDataFromCache() anterior, si no hay datos, llamamos a OnCompleted directamente. Si no llamamos a OnCompleted pero llamamos a OnError, entonces el uso de concat mencionado anteriormente no obtendrá ningún resultado. Porque cuando Concat recibe algún error, la fusión se detendrá. Por lo tanto, si desea usar OnError, debe usar ConcatDelayError en lugar de concat.concatDelayError ConcatDelayError ignorará el error primero y pospondrá el error hasta el procesamiento final.
Resumir
Lo anterior es todo el contenido de este artículo. Espero que el contenido de este artículo sea de ayuda para su estudio o trabajo. Si tiene alguna pregunta, puede dejar un mensaje para comunicarse.