第一个栗子
var button = document.querySelector('button');
button.addEventListener('click', () => console.log('Clicked!'));
// With RxJS
var button = document.querySelector('button');
Rx.Observable.fromEvent(button, 'click')
.subscribe(() => console.log('Clicked!'));
初识:RxJS 是一个库,它通过使用 observable 序列来编写异步和基于事件的程序。它提供了一个核心类型 Observable,附属类型 (Observer、 Schedulers、 Subjects) 和操作符 (map、filter、reduce、every, 等等),这些数组操作符可以把异步事件作为集合来处理。
Observable 简述
Observables 是多个值的惰性推送集合。
var observable = Rx.Observable.create(function (observer) {
observer.next(1);
observer.next(2);
observer.next(3);
setTimeout(() => {
observer.next(4);
observer.complete();
}, 1000);
});
console.log('just before subscribe');
// 当订阅下面代码中的 Observable 的时候会立即(同步地)推送值1、2、3,然后1秒后会推送值4,然后完成流。也就是,只有订阅之后,observable 才执行。
observable.subscribe({
next: x => console.log('got value ' + x),
error: err => console.error('something wrong occurred: ' + err),
complete: () => console.log('done'),
});
console.log('just after subscribe');
执行结果:
just before subscribe
got value 1
got value 2
got value 3
just after subscribe
got value 4
done
RxJS 引入了 Observables,它是多个值的生产者,并将值“推送”给观察者(数据消费者)。
Observables 可以作为函数的泛化(大白话:Observables 可以作为函数使用,但是要比普通函数强大)
Observables 像是没有参数, 但可以泛化为多个值的函数。
使用 Observables 之前:
function foo() {
console.log('Hello');
return 42;
}
var x = foo.call(); // 等同于 foo()
console.log(x);
var y = foo.call(); // 等同于 foo()
console.log(y);
使用 Observables 之后:
var foo = Rx.Observable.create(function (observer) {
console.log('Hello');
observer.next(42);
});
foo.subscribe(function (x) {
console.log(x);
});
foo.subscribe(function (y) {
console.log(y);
});
可以发现,订阅 Observable 就类似于调用函数。Rx.Observable.create 则类似于定义函数。
同步 OR 异步
上代码举栗子:
console.log('before');
console.log(foo.call());
console.log('after');
console.log('before');
foo.subscribe(function (x) {
console.log(x);
});
console.log('after');
这两段的代码输出其实是一样的。这也就证明了 foo 的订阅是完全同步的,就像普通的函数。
Observables 传递值可以是同步的,也可以是异步的。
var foo = Rx.Observable.create(function (observer) {
console.log('Hello');
observer.next(42); // 同步执行
observer.next(100); // 同步执行
observer.next(200); // 同步执行
setTimeout(() => {
observer.next(300); // 异步执行
}, 1000);
});
console.log('before');
foo.subscribe(function (x) {
console.log(x);
});
console.log('after');
结论:
func.call() // 意思是 "同步地给我一个值"
observable.subscribe() // 意思是 "给我任意数量的值,无论是同步还是异步"
Observable 详细解说
创建 Observable
核心方法:Rx.Observable.create
var observable = Rx.Observable.create(function subscribe(observer) {
var id = setInterval(() => {
observer.next('hi')
}, 1000);
});
订阅 Observable
observable.subscribe(x => console.log(x));
重复说一遍,订阅 Observable 像是调用函数, 并提供接收数据的回调函数。
执行 Observables
Observable.create(function subscribe(observer) {…}) 中…的代码表示 “Observable 执行”,它是惰性运算,只有在每个观察者订阅后才会执行。随着时间的推移,执行会以同步或异步的方式产生多个值。
Observable 执行可以传递三种类型的值:
“Next” 通知: 发送一个值,比如数字、字符串、对象,等等。
“Error” 通知: 发送一个 JavaScript 错误 或 异常。
“Complete” 通知: 不再发送任何值。
“Next” 通知是最重要,也是最常见的类型:它们表示传递给观察者的实际数据。”Error” 和 “Complete” 通知可能只会在 Observable 执行期间发生一次,并且只会执行其中的一个。
栗子:
var observable = Rx.Observable.create(function subscribe(observer) {
try {
observer.next(1);
observer.next(2);
observer.next(3);
observer.complete();
observer.next(4); // 不会执行
} catch (err) {
observer.error(err); // 如果捕获到异常会发送一个错误
}
});
清理 Observable 执行
var observable = Rx.Observable.from([10, 20, 30]);
var subscription = observable.subscribe(x => console.log(x));
// 清理 Observable 执行的方法
subscription.unsubscribe();
Observer
方法 observable.subscribe 接受的参数就是 Observer (观察者),它其实只是一组回调函数的集合,每个回调函数对应一种 Observable 发送的通知类型:next、error 和 complete 。
observable.subscribe(observer);
RxJS 中的观察者也可能是部分的。如果你没有提供某个回调函数,Observable 的执行也会正常运行,只是某些通知类型会被忽略,因为观察者中没有没有相对应的回调函数。
observable.subscribe(x => console.log('Observer got a next value: ' + x));
而这种情况,只提供了一个毁掉函数。在 observable.subscribe 内部,它会创建一个观察者对象并使用第一个回调函数参数作为 next 的处理方法。
Subscription
即订阅,它的参数就是上面的 Observer。它表示了 Observable 的执行。
Subscription 有一个重要的方法,即 unsubscribe,它不需要任何参数,只是用来清理由 Subscription 占用的资源。
栗子:
var observable = Rx.Observable.interval(1000);
var subscription = observable.subscribe(x => console.log(x));
// 稍后:
// 这会取消正在进行中的 Observable 执行
// Observable 执行是通过使用观察者调用 subscribe 方法启动的
subscription.unsubscribe();
更多内容,参见:http://cn.rx.js.org/manual/overview.html
以及:https://juejin.im/post/58cd146a61ff4b0060277d32/?utm_source=gold-miner&utm_medium=readme&utm_campaign=github