javascript ajax error-handling rxjs reactive-extensions-js

javascript - RxJS continúa escuchando después de un error Ajax



error-handling reactive-extensions-js (3)

Me encontré con mis propios problemas al interpretar cómo funcionaba esto (y onErrorResumeNext ). La lucha que encontré fue con el contexto al que se aplicó la captura (o el resumen ). La traducción coloquial simple que tiene sentido para mí es la siguiente:

Dado un flujo (u observable) de observables, catch (u onErrorResumeNext ) consumirá el error y le permitirá proporcionar uno o más observables para continuar con el flujo original.

La clave para quitar es que su fuente original se interrumpe y se reemplaza con los observables que proporciona en la función catch / onErrorResumeNext . Esto significa que si tuvieras algo como esto:

var src = Rx.Observable .interval(500) .take(10) .select(function(x) { if (x == 5) { return Rx.Observable.throw(''Simulated Failure''); } return Rx.Observable.return(x * 2); })

Luego, agregar .catch(Rx.Observable.return(''N/A'')) o .onErrorResumeNext(Rx.Observable.return(''N/A'')) no continuará simplemente su transmisión (obtenida por el interval ), pero más bien termina la corriente con un observable final (el N/A ).

Si está buscando manejar el fallo con gracia y continuar con el flujo original, debe hacer algo más parecido a .select(function(x) { return x.catch(Rx.Observable.return(''N/A'')); }) . Ahora su flujo reemplazará cualquier elemento observable en el flujo que falla con un valor predeterminado capturado y luego continuará con el flujo de origen existente.

var src = Rx.Observable .interval(500) .take(10) .select(function(x) { if (x == 5) { return Rx.Observable.throw(''Simulated Failure''); } return Rx.Observable.return(x * 2); }) //.catch(Rx.Observable.return(''N/A'')) //.onErrorResumeNext(Rx.Observable.return(''N/A'')) .select(function(x) { return x.catch(Rx.Observable.return(''N/A'')); }) .selectMany(function(x) { return x; }); var sub = src.subscribe( function (x) { console.log(x); }, function (x) { console.log(x); }, function () { console.log(''DONE''); } ); // OUTPUT: // 0 // 2 // 4 // 6 // 8 // N/A // 12 // 14 // 16 // 18 // DONE

Aquí hay un JSFiddle que muestra esto en acción.

RxJs deja de escuchar los eventos de clics cuando se produce un error interno observable (solicitud Ajax). Estoy tratando de averiguar cómo mantener al oyente de eventos conectado al evento de clic de botón y manejar con gracia el error interno de ajax.

Aquí está mi código de ejemplo y un enlace a plunkr

var input = $("#testBtn"); var test = Rx.Observable.fromEvent(input,''click''); var testAjax = function() { return Rx.Observable.range(0,3).then(function(x){ if(x==2)throw "RAWR"; //Simulating a promise error. return x; }); } test.map(function(){ return Rx.Observable.when(testAjax()); }) .switchLatest() .subscribe( function (x) { console.log(''Next: '', x); }, function (err) { console.log(''Error: '' + err); }, function () { console.log(''Completed''); });

http://plnkr.co/edit/NGMB7RkBbpN1ji4mfzih


Puede usar el operador de catch (o el alias de catchException ) para detectar y manejar los errores que ocurren en un observable, para que los suscriptores no sean notificados del error.

Ignorar errores:

return Rx.Observable .when(testAjax()) .catch(Rx.Observable.empty()); // continues with an empty obs after error.

Manejar errores:

var empty = Rx.Observable.return(''default value''); return Rx.Observable .when(testAjax()) .catch(function (error) { console.log(''error:'', error); return empty; });


Todavía estaba un poco confundido después de intentar la respuesta aceptada, así que esto es lo que terminó trabajando para mí. Esto es lo que yo tenía:

Rx.Observable.fromEvent(emitter, events.SUBMIT_EVENT) .flatMapFirst(email=>{ return $.ajax({ method: "POST", url: ''/email'', data: { email: email }, }).promise() }) .subscribe(response=>{ if (response) { //do your success thing here } }, error =>{ //do your error thing } )

Cuando el servidor devolvió un error (como cuando el usuario ya ingresó su correo electrónico) no pude escuchar el formulario de correo electrónico del usuario enviado nuevamente. Esto es lo que funcionó para mí:

Rx.Observable.fromEvent(emitter, events.SUBMIT_EVENT) .flatMapFirst(email=>{ return $.ajax({ method: "POST", url: ''/email'', data: { email: email }, }).promise() }) .doOnError(error=> { //do your error thing here }) .retry() .subscribe(response=>{ if (response) { //do your success thing here } })