`map`方法在RxJS中意味着什么?

时间:2015-01-23 10:37:33

标签: javascript rxjs

我正在通过阅读本教程http://reactive-extensions.github.io/learnrx/来学习RxJS

我很难理解Observable的{​​{3}}方法。 Arraymap非常简单直接。我不知道mapObservable的情况下究竟是什么意思(为什么它有一个名为select的别名?!)。

以下是文档告诉我的内容。可能对大多数初学者没有帮助......

  

通过合并元素的索引,将可观察序列的每个元素投影到新表单中。这是select方法的别名。

我在map的背景下不理解event。 例如,下面的代码完全符合我的预期。我认为这段代码为:“从click-event的事件流中收听#btn

var btnClicks, observable;

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

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

但是当它变成这个时会发生什么?

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);
});

我的想法是使用map将点击事件的集合转换为另一个事件集合集合。 filter很容易理解,就像单词filter的含义一样,只对我感兴趣的事件,并跳过其他人。但map背景下event怎么样?如果它意味着'将一个集合转换为另一个集合'就像数组版本一样,为什么它在#btn点击时仍会触发?

我的意思是我将它映射到另一个集合,现在它不再是#btn的点击事件的集合,但它是一个新的集合......但它仍然在#btn时触发点击对我来说没有意义。

2 个答案:

答案 0 :(得分:31)

map对于Observables的工作方式与对数组的工作方式完全相同。您使用map将项目集合转换为不同项目的集合。如果你认为Observable是一个项集合(就像一个数组也是一个项集合),这是有帮助的,至少从观察者的角度来看。

例如,将您编写的这两种方法用于某些数组:

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 observable实现了像mapfilter这样的数组运算符,它们具有与数组完全相同的语义。如果您知道它们如何用于数组,那么您就知道它们如何用于可观察数据。

这个技巧是dual nature of observables and enumerables

的结果

如果您正在查看正在查看的互动教程,它实际上会引导您完成此过程。我相信它是通过为数组编写地图运算符而开始的,然后在后来的教程中将一个可观察的信息作为源代码。

P.S。 它是select的别名,因为它的历史:Reactive Extensions首先在.NET中实现,后来移植到其他语言。 Rx.NET使用.NET的LINQ使用的相同运算符(因为IObservableIEnumerable的对偶)。 LINQ的map运算符称为Select(其过滤运算符称为Where)。这些名字来自LINQ的起源。构建LINQ时的目标之一是使用C#编写数据库查询成为可能。因此,他们为许多运算符采用SQL命名约定(LINQ SELECT直接映射到SQL SELECT,LINQ WHERE映射到SQL WHERE等)。

答案 1 :(得分:3)

用于投影的Rxjs中的Map,意味着您可以将数组转换为全新的数组。为了理解Map的工作原理,我们可以使用普通的javascript实现我们自己的map函数。

Array.prototype.map = function(projectionFunction){
var results=[];
this.forEach(function(item) {
results.push(projectionFunction(item));
});
return results;
};

你可以看到我编写了一个map函数,它接受一个匿名函数作为参数。这将是您应用投影转换数组的功能。在map函数中,您可以看到迭代数组中的每个项目,通过传递每个项目调用项目函数,最后投影函数的结果将推送到结果数组。

JSON.stringify([1,2,3].map(function(x){return x+1;}))

<强>输出

[2,3,4]