es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Rx.NET tiene un operador combo que combina las ventajas de Catch y Concat?

Tengo un observable al que necesitaba agregarle una demora entre las notificaciones en caso de que dos notificaciones estén demasiado cerca una de la otra, así que hice lo siguiente.

var niceAndSlowObservable =
observable
  .Select(x => Observable.Return(x))
  .Delay(1000)
  .Concat();

Funciona muy bien, no importa qué tan rápido se emitan los elementos, no recibo más de una notificación por segundo.

Ahora, tengo algún procesamiento/transformación en curso que podría resultar en una excepción, así que quiero usar catch.

niceAndSlowObservable
   .Select(x => TransformationThatCouldCauseException(x))
   .Catch<mytype, exception="">(x => 
               { 
                 HandleError(x);
                 return Observable.Empty<mytype>();
                });

El problema con lo anterior es que, en caso de un error, todo el flujo se detiene, no simplemente pasa al siguiente. Antes de la llamada a Concat(), tengo “un flujo de flujos”, por lo tanto, técnicamente el siguiente en la cola debería convertirse en el valor de respaldo que estoy pensando,

Básicamente algo como el siguiente código, pero sin usar bloques try-catch y operadores Rx.

niceAndSlowObservable
   .Select(x => { 
          try { TransformationThatCouldCauseException(x); } catch () {return null;})
   .Where(x => x!= null);

¿Cómo puedo hacer eso?</mytype,>

Tags:  ,

Answer

  1. Avatar for davy.ai

    Para manejar errores sin detener el flujo, puedes utilizar el operador Catch en cada flujo interno en lugar de hacerlo en el flujo externo. Puedes hacer esto utilizando Select en lugar de SelectMany para mapear el flujo de entrada a un flujo de flujos internos, y luego aplicando el operador Catch a cada flujo interno:

    niceAndSlowObservable
        .Select(x => Observable.Return(x)
            .Delay(1000)
            .Select(_ => { 
                    try { return TransformationThatCouldCauseException(x); }
                    catch { return null; }
                })
            .Where(y => y != null)
        )
        .Concat()
    

    En este código, el operador Select mapea cada valor de entrada a un flujo de un solo valor (utilizando Return) con una demora, y luego aplica la función de transformación con manejo de errores. El flujo interno se filtra con Where para eliminar los valores nulos, y luego el operador Select externo concatena todos los flujos internos en un solo flujo de valores transformados con demoras entre ellos.

    Ten en cuenta que el operador Catch no se utiliza en este enfoque, ya que cada flujo interno maneja sus propios errores.

Comments are closed.