javascript - remove - rxjs rx angular 4
RxJs captura el error y continĂșa (3)
Tengo una lista de elementos para analizar, pero el análisis de uno de ellos puede fallar.
¿Cuál es el "Rx-Way" para detectar el error pero continuar ejecutando la secuencia
Ejemplo de código:
var observable = Rx.Observable.from([0,1,2,3,4,5])
.map(
function(value){
if(value == 3){
throw new Error("Value cannot be 3");
}
return value;
});
observable.subscribe(
function(value){
console.log("onNext " + value);
},
function(error){
console.log("Error: " + error.message);
},
function(){
console.log("Completed!");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.0.6/rx.all.js"></script>
Lo que quiero hacer en un modo no Rx:
var items = [0,1,2,3,4,5];
for (var item in items){
try{
if(item == 3){
throw new Error("Value cannot be 3");
}
console.log(item);
}catch(error){
console.log("Error: " + error.message);
}
}
Gracias por adelantado
Debe cambiar a un nuevo flujo desechable, y si se produce un error, se eliminará de manera segura y se mantendrá vivo el flujo original:
Rx.Observable.from([0,1,2,3,4,5])
.switchMap(value => {
// This is the disposable stream!
// Errors can safely occur in here without killing the original stream
return Rx.Observable.of(value)
.map(value => {
if (value === 3) {
throw new Error(''Value cannot be 3'');
}
return value;
})
.catch(error => {
// You can do some fancy stuff here with errors if you like
// Below we are just returning the error object to the outer stream
return Rx.Observable.of(error);
});
})
.map(value => {
if (value instanceof Error) {
// Maybe do some error handling here
return `Error: ${value.message}`;
}
return value;
})
.subscribe(
(x => console.log(''Success'', x)),
(x => console.log(''Error'', x)),
(() => console.log(''Complete''))
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.4.1/Rx.min.js"></script>
Más información sobre esta técnica en esta publicación de blog: La búsqueda de albóndigas: Continuar las transmisiones de RxJS cuando se producen errores
En realidad, puede usar try / catch dentro de su función de mapa para manejar el error. Aquí está el fragmento de código
var source = Rx.Observable.from([0, 1, 2, 3, 4, 5])
.map(
function(value) {
try {
if (value === 3) {
throw new Error("Value cannot be 3");
}
return value;
} catch (error) {
console.log(''I caught an error'');
return undefined;
}
})
.filter(function(x) {
return x !== undefined; });
source.subscribe(
function(value) {
console.log("onNext " + value);
},
function(error) {
console.log("Error: " + error.message);
},
function() {
console.log("Completed!");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.0.6/rx.all.js"></script>
Sugeriría que use flatMap
(ahora mergeMap
en rxjs versión 5), que le permitirá colapsar errores si no se preocupa por ellos. Efectivamente, creará un Observable interno que se puede tragar si ocurre un error. La ventaja de este enfoque es que puede encadenar a los operadores y, si se produce un error en algún lugar de la tubería, se enviará automáticamente al bloque catch.
var observable = Rx.Observable.from([0, 1, 2, 3, 4, 5])
.flatMap((value) =>
Rx.Observable.if(() => value != 3,
Rx.Observable.just(value),
Rx.Observable.throw(new Error("Value cannot be 3")))
//This will get skipped if upstream throws an error
.map(v => v * 2)
.catch((err) => {
console.log("Caught Error, continuing")
//Return an empty Observable which gets collapsed in the output
return Rx.Observable.empty();
})
);
observable.subscribe(
(value) => console.log("onNext " + value), (error) => console.log("Error: " + error.message), () => console.log("Completed!")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.0.6/rx.all.js"></script>