我正在通过阅读本教程http://reactive-extensions.github.io/learnrx/
来学习RxJS。
我很难理解Observable
的{{3}}方法。 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);
});
但是当它变成这个时会发生什么?
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
时触发点击对我来说没有意义。
答案 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实现了像map
和filter
这样的数组运算符,它们具有与数组完全相同的语义。如果您知道它们如何用于数组,那么您就知道它们如何用于可观察数据。
这个技巧是dual nature of observables and enumerables。
的结果如果您正在查看正在查看的互动教程,它实际上会引导您完成此过程。我相信它是通过为数组编写地图运算符而开始的,然后在后来的教程中将一个可观察的信息作为源代码。
P.S。
它是select
的别名,因为它的历史:Reactive Extensions首先在.NET中实现,后来移植到其他语言。 Rx.NET使用.NET的LINQ使用的相同运算符(因为IObservable
是IEnumerable
的对偶)。 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]