RXJS
简介
rxjs通过observable序列编写异步和基于事件的程序。它的内容可以概括为一个核心三个重点,
核心是Observable
和Operators
,重点是observer
Subject
schedulers
。
Observable(可观察对象)
Observable一个新的推送体系,它是多个值的生产者,并将值推送给观察者;
Observable
像是没有参数,但可以泛化为多个值的函数
Observable与function的共同点
例如:function
function foo() {
console.log('Hello');
return 42;
}
var x = foo.call(); // 等同于foo()
console.log(x);
var y = foo.call(); //等同于foo()
console.log(y);
"Hello"
42
"Hello"
42
使用Observable重写上边代码:
var foo = Rx.Observable.create(function (observable) {
console.log('Hello');
observer.next(42);
})
foo.subscrible(function (x) {
console.log(x);
})
foo.subscrible(function (y) {
console.log(y);
})
"Hello"
42
"Hello"
42
订阅函数和Observable都是惰性运算。如果不调用函数console.log
也不会执行, 不订阅Observable也不会执行console.log
。
订阅Observable类似于调用函数,并且也是异步的。
Observable与函数的不同点
Observable随着时间的推移可以’返回‘多个值,这个能力是函数做不到的。
例如:function
function foo() {
console.log('Hello');
return 42;
return 100; //之后的return都不会执行
}
Observable可以这样
var foo = Rx.Observable.create(function (observer) {
console.log('Hello');
observer.next(42);
observer.next(100); // 返回另外一个值
observer.next(200); //再返回另外一个值
})
console.log('before');
foo.subscrible(function (x) {
console.log(x);
});
console.log('after');
"before"
"Hello"
42
100
200
"after"
另外也可以异步地返回值
var foo = Rx.Observable.create(function (observer) {
console.log('Hello');
observer.next(42);
observer.next(100); // 返回另外一个值
setTimeout(() => {
observer.next(200); //再返回另外一个值
})
})
console.log('before');
foo.subscrible(function (x) {
console.log(x);
});
console.log('after');
"before"
"Hello"
42
100
"after"
200
Observable 方法
Observable通过Rx.Observable.create 或创建操作符创建,并且使用观察者来订阅它,然后执行并且发送next
/error
/complete
通知观察者
Observable的核心
- 创建
- 订阅
- 执行
- 清理
创建Observable:
Rx.Observable.create
是Observable构造函数的别名,他接受一个参数:subscrible函数
Observables 可以使用 create
来创建, 但通常我们使用所谓的创建操作符, 像 of
、from
、interval
、等等。
var observable = Rx.Observable.create(function subscribe(observer) {
var id = setInterval(() => {
observer.next('hi')
}, 1000);
});
订阅Observables
订阅Observable像是调用函数,并提供接受数据的回调函数
observable.subscribe(x => console.log(x));
执行Observables
Observable.create(function subscribe(observer) {...})
中的{...}
表示Observable的执行,它是惰性运算,当每个观察者订阅后才执行,随着时间的推移它会同步或者异步产生多个值。
Observable传递时可以传递多个值:
Next
通知:发送一个值,数字,字符串,对象等等;Error
通知:发送一个JavaScript异常或者错误;Complete
通知: 不再发送任何值
“Next” 通知是最重要,也是最常见的类型:它们表示传递给观察者的实际数据。“Error” 和 “Complete” 通知可能只会在 Observable 执行期间发生一次,并且只会执行其中的一个。
在 Observable 执行中, 可能会发送零个到无穷多个 "Next" 通知。如果发送的是 "Error" 或 "Complete" 通知的话,那么之后不会再发送任何通知了。
使用Complete之后,在使用Next将会无效
var observable = Rx.Observable.create(function subscrible(observer) {
observer.next(1);
observer.complete(); //complete之后next将不会发送
observer.next(2)
})
可以在subscribe中通过try/catch
来包裹代码,来捕获错误,会发送error通知。
var observable = Rx.Observable.create(function subscrible(observer) {
try {
observer.next(1);
observer.complete();
} catch (err) {
observer.error(err);
}
})
Observer (观察者)
观察者是由Observable发送的值的消费者,它是一组回调函数的集合,每个回调函数对应一种发送通知类型: next
,error
,complete
var observer = {
next: x => console.log('Observer got a next value:' + x),
error: err => console.log('Observer got a error: ' + err),
complete: () => console.log('Observer got a complete')
}
观察者只是有三个回调函数的对象,每个回调函数对应一种Observable发送的通知类型
当订阅 Observable
时,可能只提供了一个回调函数作为参数,并没有将其附加到观察者对象上
在observable.subscribe
内部,他会创建一个观察者对象并且将第一个回调函数作为next的处理方法
observable.subscribe(
x => console.log('Observer got a next value:' + x),
error: err => console.error('Observer got a error:' + err),
() => console.log('Observer got a complete')
)
Subscription(订阅)
Subscription表示可清理资源的对象,通常是Observable的执行,他有一个重要的方法:unsubscribe
, 他不需要任何参数,只是用来清理Subscription占用的资源。
var observable = Rx.Observable.interval(1000);
var subscription = observable.subscribe(x => console.log(x));
// 稍后:
// 这会取消正在进行中的 Observable 执行
// Observable 执行是通过使用观察者调用 subscribe 方法启动的
subscription.unsubscribe();
Subscription基本上只有一个unsubscribe()函数,这个函数用来释放资源或取消Observable执行
Subject(主体)
Subject是一种特殊类型的Observable,它允许将值多播给多个观察者,普通的Observable是单播的
1.每个Subject都是Observable,对于Subject,可以提供一个观察者并使用subscribe方法就可以正常读值,从观察者角度来说是不知道它是来自Observable还是Subject的
2.每个Subject都是一个观察者,他是有如下方法的对象: next()
,error()
,complete()
。想要提供新值只需要调用next(theValue)
var subject = new Rx.Subject();
subject.subscribe({
next: (v) => console.log('observerA:' + v)
});
subject.subscribe({
next: (v) => console.log('observerB:' + v)
});
subject.next(1);
subject.next(2);
// observerA: 1
// observerB: 1
// observerA: 2
// obserberB: 2
理解:Subject是先创建方法然后被调用的时候传值进行调用它类似函数,Obsevable更类似于把将要传入的值(即next,error,complete中的值)看作是观察者,之后调用的时候进行相应情况的处理
因为Subject是观察者,可以将Subject作为参数传入Observable的subscribe方法
var subject = new Rx.Subject();
subject.subscribe({
next: (v) => console.log('observerA:' + v)
});
subject.subscribe({
next: (v) => console.log('observerB:' + v)
});
var observable = Rx.Observable.from([1, 2]);
observable.subscribe(subject);
// observerA: 1
// observerB: 1
// observerA: 2
// obserberB: 2
Operatorts(操作符)
操作符是Observable类型上的方法,它是函数,它基于当前的Observable创建一个新的Observable,并且没有副作用,之前的Observable保持不变
操作符本质是一个纯函数,它接受一个Observable作为输入,并生成一个新的Observable作为输出。订阅输出Observable也会订阅输入Observable。
例:输入Observable
function multiplyByTen(input) {
var output = Rx.Observable.create(function subscribe(observer) {
input.subscribe({
next: (v) => observer.next(10 * v),
error: (err) => observer.error(err),
complete: () => observer.complete()
});
});
return output;
}
var input = Rx.Observable.from([1, 2, 3, 4]);
var output = multiplatByTen(input);
output.subscribe(x => console.log(x));
// 10
// 20
// 30
// 40
订阅
output会导致
inputObservable 也被订阅。我们称之为“操作符订阅链”。
实例操作符 静态操作符
实例操作符
一般提到操作符的时候,指的都是实例操作符,他是observable实例上的方法,比方上边方法如果是官方提供的实例操作符,那么他大概是这个样子
Rx.Observable.prototype.multiplyByTen = function multiplyByTen() {
var input = this;
return Rx.Observable.create(function subscribe(observer) {
input.subscribe({
next: (v) => observer.next(10 * v),
error: (err) => observer.error(err),
complete: () => observer.complete()
});
});
}
// 使用
var observable = Rx.Observable.from([1, 2, 3, 4]).multiplyByTen();
observable.subscribe(x => console.log(x));
实例运算符使用this关键字来指输入的Observable的函数。
静态操作符
静态操作符是附加到Observable类上的纯函数,通常用来从头开始创建Observable