Skip to content

Instantly share code, notes, and snippets.

@toioski
Created August 29, 2017 14:46
Show Gist options
  • Save toioski/de65453ef5ceb171f4fcf764b3a38607 to your computer and use it in GitHub Desktop.
Save toioski/de65453ef5ceb171f4fcf764b3a38607 to your computer and use it in GitHub Desktop.
switchMap vs mergeMap deep explained (source http://jsbin.com/hehaqi)
<!DOCTYPE html>
<html>
<head>
<meta name="description" content="[switchMap vs mergeMap of RxJS]">
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/2.3.22/rx.all.js"></script>
<title>JS Bin</title>
<script src="http://cdn.jsdelivr.net/rsvp/3.0.6/rsvp.js"></script>
</head>
<body>
<script id="jsbin-javascript">
"use strict";
function simulateHttp(val, delay) {
return Rx.Observable.of(val).delay(delay).map(function (index) {
return val + " " + index;
});
}
// Emette 'val' ogni 'delay' ms
function simulateFirebase(val, delay) {
return Rx.Observable.interval(delay).map(function (index) {
return val + " " + index;
});
}
var outer$ = simulateFirebase("Outer observable", 5000);
var inner$ = simulateFirebase("|___Inner observable", 1000);
// FONDAMENTALE: switchMap e mergeMap hanno senso solo con gli high-order Observable, ovvero
// Observable che ritornano Observable.
// switchMap
/**
* Il concetto fondamentale è la funzione 'switch' di RxJS.
* Questa funzione lavora con due Observable: uno Observable 'esterno' e un Observable 'interno'. Quest'ultimo
* corrisponde al ritorno dell'Observable esterno (da cui il nome). La funzione 'switch' non fa altro
* che ritornare un unico Observable dove ogni volta che l'Observable esterno emette viene fatto il subscribe
* (ovvero si switcha) all'observable interno il quale detterà gli eventi. Nel momento in cui l'observable esterno
* emette di nuovo quello interno muore e ne viene creato uno nuovo
*/
// .range(n,m) emette interi che vanno da n ad n+m-1
var switchSource = Rx.Observable.range(0, 3).map(function (x) {
return Rx.Observable.range(x, 3);
}) //.map() e .select() sono alias
["switch"]();
var switchSubscription = switchSource.subscribe(function (x) {
console.log('Next: ' + x);
}, function (err) {
console.log('Error: ' + err);
}, function () {
console.log('Completed');
});
/**
* 0. switchMap non è altro che la combinazione di quello che sopra è .map() e .switch()
* 1. Importantissimo (è la vera differenza con mergeMap): ogni volta che l'Observable esterno emette un evento
* l'observable interno viene ucciso e ne viene creato uno nuovo (ovvero viene fatto lo switch)
* 2. Quindi si deduce che il tempo di vita dell'observable interno è pari al periodo dell'observable esterno
*/
var switchResult$ = outer$.switchMap(function (value) {
console.log(value);
return inner$.map(function (val) {
return val + " (" + value + ")";
});
});
// mergeMap
/**
* 1. flatMap e mergeMap sono alias della stessa funzione
* 2. Ogni volta che l'Observable esterno emette un evento l'observable interno non viene ucciso,
* ma ne viene creato uno nuovo e il vecchio viene lasciato in esecuzione
* 3. Quindi si deduce che viene creato un nuovo observable interno
* ogni intervallo pari al periodo dell'observable esterno
*/
var mergeResult$ = outer$.flatMap(function (value) {
console.log(value);
return inner$;
});
// Decommentare i subscribe in base a cosa si vuole testare
/*
switchResult$.subscribe(
console.log,
console.error,
() => console.log('completed')
);
*/
/*
mergeResult$.subscribe(
console.log,
console.error,
() => console.log('completed firebaseResult$')
);
*/
</script>
<script id="jsbin-source-html" type="text/html"><!DOCTYPE html>
<html>
<head>
<meta name="description" content="[switchMap vs mergeMap of RxJS]">
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/2.3.22/rx.all.js"><\/script>
<title>JS Bin</title>
<script src="//cdn.jsdelivr.net/rsvp/3.0.6/rsvp.js"><\/script>
</head>
<body>
</body>
</html></script>
<script id="jsbin-source-javascript" type="text/javascript">
function simulateHttp(val: any, delay:number) {
return Rx.Observable.of(val).delay(delay).map(index => val + " " + index);
}
// Emette 'val' ogni 'delay' ms
function simulateFirebase(val: any, delay: number) {
return Rx.Observable.interval(delay).map(index => val + " " + index);
}
const outer$ = simulateFirebase("Outer observable", 5000);
const inner$ = simulateFirebase("|___Inner observable", 1000);
// FONDAMENTALE: switchMap e mergeMap hanno senso solo con gli high-order Observable, ovvero
// Observable che ritornano Observable.
// switchMap
/**
* Il concetto fondamentale è la funzione 'switch' di RxJS.
* Questa funzione lavora con due Observable: uno Observable 'esterno' e un Observable 'interno'. Quest'ultimo
* corrisponde al ritorno dell'Observable esterno (da cui il nome). La funzione 'switch' non fa altro
* che ritornare un unico Observable dove ogni volta che l'Observable esterno emette viene fatto il subscribe
* (ovvero si switcha) all'observable interno il quale detterà gli eventi. Nel momento in cui l'observable esterno
* emette di nuovo quello interno muore e ne viene creato uno nuovo
*/
// .range(n,m) emette interi che vanno da n ad n+m-1
var switchSource = Rx.Observable.range(0, 3)
.map(function (x) { return Rx.Observable.range(x, 3); }) //.map() e .select() sono alias
.switch();
var switchSubscription = switchSource.subscribe(
function (x) { console.log('Next: ' + x); },
function (err) { console.log('Error: ' + err); },
function () { console.log('Completed'); });
/**
* 0. switchMap non è altro che la combinazione di quello che sopra è .map() e .switch()
* 1. Importantissimo (è la vera differenza con mergeMap): ogni volta che l'Observable esterno emette un evento
* l'observable interno viene ucciso e ne viene creato uno nuovo (ovvero viene fatto lo switch)
* 2. Quindi si deduce che il tempo di vita dell'observable interno è pari al periodo dell'observable esterno
*/
const switchResult$ = outer$.switchMap(value => {
console.log(value);
return inner$.map(val => val + " (" + value + ")")
});
// mergeMap
/**
* 1. flatMap e mergeMap sono alias della stessa funzione
* 2. Ogni volta che l'Observable esterno emette un evento l'observable interno non viene ucciso,
* ma ne viene creato uno nuovo e il vecchio viene lasciato in esecuzione
* 3. Quindi si deduce che viene creato un nuovo observable interno
* ogni intervallo pari al periodo dell'observable esterno
*/
const mergeResult$ = outer$.flatMap(value => {
console.log(value);
return inner$
})
// Decommentare i subscribe in base a cosa si vuole testare
/*
switchResult$.subscribe(
console.log,
console.error,
() => console.log('completed')
);
*/
/*
mergeResult$.subscribe(
console.log,
console.error,
() => console.log('completed firebaseResult$')
);
*/</script></body>
</html>
"use strict";
function simulateHttp(val, delay) {
return Rx.Observable.of(val).delay(delay).map(function (index) {
return val + " " + index;
});
}
// Emette 'val' ogni 'delay' ms
function simulateFirebase(val, delay) {
return Rx.Observable.interval(delay).map(function (index) {
return val + " " + index;
});
}
var outer$ = simulateFirebase("Outer observable", 5000);
var inner$ = simulateFirebase("|___Inner observable", 1000);
// FONDAMENTALE: switchMap e mergeMap hanno senso solo con gli high-order Observable, ovvero
// Observable che ritornano Observable.
// switchMap
/**
* Il concetto fondamentale è la funzione 'switch' di RxJS.
* Questa funzione lavora con due Observable: uno Observable 'esterno' e un Observable 'interno'. Quest'ultimo
* corrisponde al ritorno dell'Observable esterno (da cui il nome). La funzione 'switch' non fa altro
* che ritornare un unico Observable dove ogni volta che l'Observable esterno emette viene fatto il subscribe
* (ovvero si switcha) all'observable interno il quale detterà gli eventi. Nel momento in cui l'observable esterno
* emette di nuovo quello interno muore e ne viene creato uno nuovo
*/
// .range(n,m) emette interi che vanno da n ad n+m-1
var switchSource = Rx.Observable.range(0, 3).map(function (x) {
return Rx.Observable.range(x, 3);
}) //.map() e .select() sono alias
["switch"]();
var switchSubscription = switchSource.subscribe(function (x) {
console.log('Next: ' + x);
}, function (err) {
console.log('Error: ' + err);
}, function () {
console.log('Completed');
});
/**
* 0. switchMap non è altro che la combinazione di quello che sopra è .map() e .switch()
* 1. Importantissimo (è la vera differenza con mergeMap): ogni volta che l'Observable esterno emette un evento
* l'observable interno viene ucciso e ne viene creato uno nuovo (ovvero viene fatto lo switch)
* 2. Quindi si deduce che il tempo di vita dell'observable interno è pari al periodo dell'observable esterno
*/
var switchResult$ = outer$.switchMap(function (value) {
console.log(value);
return inner$.map(function (val) {
return val + " (" + value + ")";
});
});
// mergeMap
/**
* 1. flatMap e mergeMap sono alias della stessa funzione
* 2. Ogni volta che l'Observable esterno emette un evento l'observable interno non viene ucciso,
* ma ne viene creato uno nuovo e il vecchio viene lasciato in esecuzione
* 3. Quindi si deduce che viene creato un nuovo observable interno
* ogni intervallo pari al periodo dell'observable esterno
*/
var mergeResult$ = outer$.flatMap(function (value) {
console.log(value);
return inner$;
});
// Decommentare i subscribe in base a cosa si vuole testare
/*
switchResult$.subscribe(
console.log,
console.error,
() => console.log('completed')
);
*/
/*
mergeResult$.subscribe(
console.log,
console.error,
() => console.log('completed firebaseResult$')
);
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment