RxJS 中的 `map` 方法是什么意思?

What does the `map` method mean in RxJS?

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

我很难理解Observablemap方法。 mapArray 版本非常简单明了。我不知道 mapObservable 的情况下到底是什么意思(以及为什么它有一个名为 select 的别名?!)。

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

Projects each element of an observable sequence into a new form by incorporating the element's index. This is an alias for the select method.

event 的上下文中,我不理解 map。 例如,下面的代码完全符合我的预期。我认为这段代码是:"Listen to the click-event from the event-stream of #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这个词的意思,只取我感兴趣的事件,其他的跳过。但是 event 上下文中的 map 呢?如果它意味着 'transform a collection to another ones' 就像数组版本一样,为什么当 #btn 单击时它仍然会触发?

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

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

这个技巧是dual nature of observables and enumerables的结果。

如果您完成正在查看的交互式教程,它实际上会引导您完成此过程。我相信它是通过为数组编写映射运算符开始的,然后在以后的教程中偷偷将一个 observable 作为源。

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

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

实现我们自己的 map 函数
Array.prototype.map = function(projectionFunction){
  var results=[];
  this.forEach(function(item) {
    results.push(projectionFunction(item));
  });
  return results;
};

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

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

输出

[2,3,4]