Created
August 29, 2017 14:46
-
-
Save toioski/de65453ef5ceb171f4fcf764b3a38607 to your computer and use it in GitHub Desktop.
switchMap vs mergeMap deep explained (source http://jsbin.com/hehaqi)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"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