Что означает метод "map" в RxJS?

Я изучаю RxJS, прочитав этот учебник http://reactive-extensions.github.io/learnrx/.

Мне трудно понять способ map Observable. Версия Array map действительно проста и проста. Я не знаю, что именно означает map в случае Observable (и почему у него есть псевдоним с именем select?!).

Вот что мне рассказала документация. Не может быть полезно для большинства новичков...

Проецирует каждый элемент наблюдаемой последовательности в новую форму путем включения индекса элемента. Это псевдоним для метода select.

Я не понимаю map в контексте event. Например, приведенный ниже код работает точно так, как я ожидал. Я подумал об этом фрагменте кода: "Прослушайте click-event из потока событий #btn".

var btnClicks, observable;

btnClicks = Rx.Observable.fromEvent($('#btn'), "click");

observable = btnClicks.subscribe(function(e) {
	console.log(e);
});

Ответ 1

map работает точно так же для Observables, как и для массивов. Вы используете map, чтобы преобразовать коллекцию элементов в коллекцию разных элементов. Это помогает, если вы думаете о Observable как о наборе элементов (подобно тому, как массив также представляет собой набор элементов), по крайней мере, с точки зрения наблюдателя.

Например, возьмите эти 2 метода, которые вы написали, для использования с некоторыми массивами:

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]

Вы можете использовать эти же функции для наблюдаемого:

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]

Это возможно, потому что наблюдаемые переменные RxJs реализуют такие операторы массива, как map и filter, чтобы иметь ту же семантику, что и для массивов. Если вы знаете, как они работают для массивов, то вы знаете, как они работают для наблюдаемых.

Этот трюк является результатом двойственной природы наблюдаемых и перечисляемых .

Если вы работаете с интерактивным учебным пособием, которое вы просматриваете, он действительно проводит вас через этот процесс. Я считаю, что это заставляет вас записывать операторы карт для массивов, а затем в более позднем учебном пособии проглядывает наблюдаемый в качестве источника.

P.S. Это псевдоним select из-за его истории: Reactive Extensions был впервые реализован в .NET, а затем перенесен на другие языки. Rx.NET использует те же операторы, которые используются .NET LINQ (поскольку IObservable является двойником IEnumerable). Оператор карты LINQ известен как select (и его оператор фильтра известен как Where). Эти имена исходят от создания LINQ. Одна из целей создания LINQ заключалась в том, чтобы сделать возможным запись запросов к базе данных на С#. Таким образом, они приняли соглашения об именах SQL для многих операторов (LINQ SELECT сопоставляет непосредственно с SQL SELECT, LINQ WHERE сопоставляется с SQL WHERE и т.д.).