简介
Rxjs的内容可以概括为一个核心三个重点,核心就是Observable和Operators,三个重点分别是:
observer
Subject
schedulers
其中众多的operator一直是我门学习Rxjs路上的拦路虎,文章主体内容也将是围绕这部分内容讲解。
简单的例子
下边用一个简单的例子来展示下Rxjs如何工作。
var observable = Observable
.create(function(observer) {
observer.next('Jerry'); // RxJS 4.x 以前的版本用 onNext
observer.next('Anna');
})
// 订阅 observable
observable.subscribe(function(value) {
console.log(value);
})
通过Observable身上的create方法可以创建一个Observable,参数中的回调函数设置这个Observable将会如何传递值,然后通过subscribe订阅这个Observable。
这里值得一提的是rxjs的subscribe是同步执行的,例如下边这段代码:
var observable = Observable
.create(function(observer) {
observer.next('Jerry'); // RxJS 4.x 以前的版本用 onNext
observer.next('Anna');
})
console.log('start');
observable.subscribe(function(value) {
console.log(value);
});
console.log('end');
最终结果为:
start
Jerry
Anna
end
通过subscribe订阅启动的代码在第二个log之后才在控制台打印,由此可以看出subscribe是同步执行的。
Rxjs的operators
学好Rxjs的operarors是学会Rxjs的关键,熟练使用Rxjs中各种各样的operators可以大大提高我门工作效率
Operators的分类
Rxjs的operattors实在太多了,于是我按照我自己的理解将Rxjs的operators进行了分类,这样有理解记忆。
本人按照自己的理解将Operators分为8类,如下图所示:
Operators分类
下边就按照分类分别对各个operator进行讲解。
创造observabl类
create
const observable = Observable.create((observe) => {
observe.next('value')
})
observable.subscribe({
next:() => {
},
complete: () => {
},
error: () => {
}
}
of
感觉of类似于一个迭代器,将参数迭代然后发出。
var source = of('Jerry', 'Anna');
source.subscribe({
next: function(value) {
console.log(value)
},
complete: function() {
console.log('complete!');
},
error: function(error) {
console.log(error)
}
});
from
from的参数必须是一个类数组(set,iterator等),其他和of一样
var arr = ['Jerry', 'Anna', 2016, 2017, '30 days']
var source = from(arr);
source.subscribe({
next: function(value) {
console.log(value)
},
complete: function() {
console.log('complete!');
},
error: function(error) {
console.log(error)
}
});
// Jerry
// Anna
// 2016
// 2017
// 30 days
// complete!
fromPromise
遍历promise,其他和前两个一样
var source = fromPromise(new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Hello RxJS!');
},3000)
}))
source.subscribe({
next: function(value) {
console.log(value)
},
complete: function() {
console.log('complete!');
},
error: function(error) {
console.log(error)
}
});
fromEvent
var source = fromEvent(document.body, 'click');
source.subscribe({
next: function(value) {
console.log(value)
},
complete: function() {
console.log('complete!');
},
error: function(error) {
console.log(error)
}
});
Empty,never和throw
empty 會給我們一個空的 observable,如果我們订阅这个 observable , 它会立即响应complete 函数。
var source = empty();
source.subscribe({
next: function(value) {
console.log(value)
},
complete: function() {
console.log('complete!');
},
error: function(error) {
console.log(error)
}
});
// complete!
throw,它也只做一件事就是拋出错误。
var source = throw('Oop!');
source.subscribe({
next: function(value) {
console.log(value)
},
complete: function() {
console.log('complete!');
},
error: function(error) {
console.log('Throw Error: ' + error)
}
});
// Throw Error: Oop!
數學上還有一個跟零(0)很像的數,那就是 無窮(∞),在 Observable 的世界裡我們用 never 來建立無窮的 observablenever 會給我們一個無窮的 observable,如果我們訂閱它又會發生什麼事呢?…什麼事都不會發生,它就是一個一直存在但卻什麼都不做的 observable。
Interval和timer
interval和setInterval一样,几秒钟发送一个值,如下边代码所示:
var source = interval(1000);
source.subscribe({
next: function(value) {
console.log(value)
},
complete: function() {
console.log('complete!');
},
error: function(error) {
console.log('Throw Error: ' + error)
}
});
// 0
// 1
// 2
// ...
参数为设定多少毫秒钟发送一个值。
timer有两个参数,第一个参数表示到发送第一个值的间隔时间,第二个参数表示从发送第二个参数开始,没发送一个值的间隔时间,如果第二个参数为空则发送第一个参数后,终止,执行complete函数。
var source = Rx.Observable.timer(1000, 5000);
source.subscribe({
next: function(value) {
console.log(value)
},
complete: function() {
console.log('complete!');
},
error: function(error) {
console.log('Throw Error: ' + error)
}
});
// 0
// 1
// 2 ...
选择器类
take
有的时候我门希望获取Observable前几个数然后结束(执行complete方法)
var source = interval(1000);
var example = source.pipe(take(3));
example.subscribe({
next: (value) => { console.log(value); },
error: (err) => { console.log('Error: ' + err); },
complete: () => { console.log('complete'); }
});
// 0
// 1
// 2
// complete
first
取第一个数然后结束,和take(1)效果一样
var source = interval(1000);
var example = source.pipe(first());
example.subscribe({
next: (value) => { console.log(value); },
error: (err) => { console.log('Error: ' + err); },
complete: () => { console.log('complete'); }
});
// 0
// complete
takeLast,last
takeLast和take用法一样,区别是该方法是取后边几个值,例子如下:
var source = interval(1000).pipe(take(6), takeLast(2));
source.subscribe({
next: value => {
console.log(value);
},
error: err => {
console.log("Error: " + err);
},
complete: () => {
console.log("complete");
}
});
// 4
// 5
// complete
last是take Last(1)的简写,目的是取最后一个值。
var source = interval(1000).pipe(take(6), last());
source.subscribe({
next: value => {
console.log(value);
},
error: err => {
console.log("Error: " + err);
},
complete: () => {
console.log("complete");
}
});
// 5
// complete
控制数据流额类
takeUntil
参数为一个Observable,当参数Observable订阅发生,终止takeUntil绑定的observable。
下边这个案例,当点击body时就会终止订阅。
const click = fromEvent(document.body, "click");
const source = interval(1000).pipe(takeUntil(click));
source.subscribe({
next: value => {
console.log(value);
},
error: err => {
console.log("Error: " + err);
},
complete: () => {
console.log("complete");
}
});
// 0
// 1
// 2
// 3
// complete 当点击body
skip
使用方式类似take,take是取前几个,skip的意思是跳过前几个,取后边几个。
const source = interval(1000).pipe(skip(3));
example.subscribe({
next: (value) => { console.log(value); },
error: (err) => { console.log('Error: ' + err); },
complete: () => { console.log('complete'); }
});
// 3
// 4
// 5...