javascript - operador - rxjs switchmap
¿Qué significa el método `map` en RxJS? (2)
Estoy aprendiendo RxJS leyendo este tutorial http://reactive-extensions.github.io/learnrx/
.
Me cuesta entender el método de map de Observable
. La versión Array
del map
es realmente simple y directa. No tengo idea de lo que significa exactamente el map
en caso de un Observable
(¿y por qué tiene un alias llamado select
?!).
Esto es lo que me dijo la documentación. Podría no ser útil para la mayoría de los principiantes ...
Proyecta cada elemento de una secuencia observable en una nueva forma incorporando el índice del elemento. Este es un alias para el método de selección.
No entiendo el map
en el contexto del event
. Por ejemplo, el siguiente código funciona exactamente lo que esperaba. Pensé en este fragmento de código como: "Escuche el click-event
de la secuencia de #btn
de #btn
".
var btnClicks, observable;
btnClicks = Rx.Observable.fromEvent($(''#btn''), "click");
observable = btnClicks.subscribe(function(e) {
console.log(e);
});
¿Pero que pasa cuando se hace esto?
var btn2Clicks, btnClicks, observable;
btnClicks = Rx.Observable.fromEvent($(''#btn''), "click");
btn2Clicks = Rx.Observable.fromEvent($(''#btn2''), "click");
observable = btnClicks.map(function(e) {
return btn2Clicks;
}).subscribe(function(e) {
console.log(e);
});
Lo que pensé es usar el map
para transformar una colección de un evento de clic en otra colección de eventos. El filter
es fácil de entender, al igual que el filter
palabras significa, tome el evento que solo me interesa y omita otros. ¿Pero qué tal el map
en el contexto del event
? Si significa "transformar una colección a otra" al igual que la versión de matriz, ¿por qué todavía se dispara cuando se #btn
clic en #btn
?
Quiero decir que lo he asignado a otras colecciones, ahora ya no es una colección de eventos de clic de #btn
pero es una nueva colección de algo ... Pero aún se dispara cuando #btn
hace clic, lo que no tiene sentido para mí.
El mapa en Rxjs utilizado para proyección, significa que puede transformar la matriz en una matriz completamente nueva. Para entender cómo funciona el Mapa, podemos implementar nuestra propia función de mapa usando javascript simple.
Array.prototype.map = function(projectionFunction){
var results=[];
this.forEach(function(item) {
results.push(projectionFunction(item));
});
return results;
};
Puede ver que he escrito una función de mapa que acepta una función anónima como parámetro. Esta será su función para aplicar la proyección para transformar la matriz. Dentro de la función de mapa, puede ver la iteración de cada elemento en una matriz, llamar a la función de proyecto al pasar cada elemento y, finalmente, el resultado de la función de proyección pasará a la matriz de resultados.
JSON.stringify([1,2,3].map(function(x){return x+1;}))
Salida
[2,3,4]
map
funciona exactamente igual para los observables que para los arreglos. Utiliza el map
para transformar una colección de artículos en una colección de artículos diferentes. Es útil si piensa en un Observable como una colección de elementos (al igual que una matriz es también una colección de elementos), al menos desde el punto de vista del observador.
Por ejemplo, tome estos 2 métodos que escribió para usar con algunas matrices:
function multiplyByTwo(collection) {
return collection.map(function (value) {
return value * 2;
});
}
function removeZeroes(collection) {
return collection.filter(function (value) {
return value !== 0;
});
}
var a = [1, 2, 3, 4, 0, 5];
var b = multiplyByTwo(a); // a new array [2, 4, 6, 8, 0, 10]
var c = removeZeroes(b); // a new array [2, 4, 6, 8, 10]
Puedes usar estas mismas funciones para un observable:
var a = Rx.Observable.of(1, 2, 3, 4, 0, 5);
var b = multiplyByTwo(a); // a new observable [2, 4, 6, 8, 0, 10]
var c = removeZeroes(b); // a new observable [2, 4, 6, 8, 10]
Esto es posible porque los observables de RxJ implementan los operadores de matriz como map
y filter
para tener la misma semántica que tienen para las matrices. Si sabes cómo funcionan para matrices, entonces sabes cómo funcionan para los observables.
Este truco es el resultado de la naturaleza dual de los observables y los enumerables .
Si trabaja a través del tutorial interactivo que está viendo, en realidad lo guiará a través de este proceso. Creo que comienza con la escritura de operadores de mapas para matrices y luego, en un tutorial posterior, toma un observable como fuente.
PS Es un alias para select
debido a su historial: las Extensiones reactivas se implementaron por primera vez en .NET y luego se portaron a otros idiomas. Rx.NET usa los mismos operadores que usa LINQ de .NET (ya que IObservable
es el dual de IEnumerable
). El operador de mapas de LINQ se conoce como Select
(y su operador de filtro se conoce como Where
). Estos nombres provienen de la originación de LINQ. Uno de los objetivos cuando se construyó LINQ fue hacer posible escribir consultas de base de datos en C #. Por lo tanto, adoptaron convenciones de denominación de SQL para muchos de los operadores (LINQ SELECT se asigna directamente a SQL SELECT, LINQ WHERE se asigna a SQL WHERE, etc.).