Observable
可观察量是一种能惰性推送的集合,他可以包含多个值。下面的表格对比了推送和拉取2种方式:
单值 | 多值 | |
---|---|---|
拉取 | Function | Iterator |
推送 | Promise | Observable |
举例来说,下列Observable 在被订阅之后会立即推送(同步)值1,2,3
,而值4
将会在1秒之后被推送到订阅者,之后这个流进入完成状态:
var obserable = Rx.Observable.create(function(observer){ //注意参数的命名
observer.next(1);
observer.next(2);
observer.next(3);
setTimeout(function(){
observer.next(4);
observer.complete();
},1000);
});
为了调用以上的Observable并输出其中的值,需要订阅这个流:
console.log('just before subscribe');
observable.subscribe({
next:x => console.log('got value:',x),
error:err => console.log('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
pull vs push 拉取 vs 推送
拉取和推送是数据生产者和数据使用者之间进行数据交换的2种形式。
什么是拉取?
在拉取系统中,数据使用者决定何时从数据生产者那里接收数据。数据生产者自身并不知道数据何时会被传递给使用者。
每一个js函数都是一个拉取系统。函数是一个数据生产者,通过在别处被调用,他返回的单一值将会被投入计算。
ES2015又引入了新的拉取系统,generator和迭代器(function*
)。调用iterator.next()
来消费从迭代器(数据生产者)中拉取到的数据。
Producer | Consumer | |
---|---|---|
Pull | 被动的:被请求的时候返回数据 | 主动的:决定数据何时被请求 |
Push | 主动的:按照自己的步骤返回数据 | 被动的:接收的数据后作出反应 |
什么是推送?
在推送系统中,数据生产者决定何时把数据推送给使用者,使用者自己并不知道何时能够接收到数据。
Promise是当今js中最常见的一种推送系统。和函数不同,Promise(数据生产者)精确的控制时机,将数据“推送”给业已注册的回调函数(数据使用者)。
RxJS引入了Observables,一个新的JS推送系统。
一个Observable是一个包含多个值的“数据生产者”,它会将数据推送给Observer(数据使用者)。
A Function is a lazily evaluated computation that synchronously returns a single value on invocation.
A generator is a lazily evaluated computation that synchronously returns zero to (potentially) infinite values on iteration.
A Promise is a computation that may (or may not) eventually return a single value.
An Observable is a lazily evaluated computation that can synchronously or asynchronously return zero to (potentially) infinite values from the time it's invoked onwards.
Function
是一种惰性计算方式,当他被调用时会同步的返回一个值。generator
是一种惰性计算方式,会在迭代中同步的返回0到无限个(可能的话)返回值。Promise
使用一种处理方法,最终可能会(或可能不会)返回一个值。Observable
是一种惰性处理方法,当被调用的时候,可以同步也可以异步的返回0到无限个(可能的话)返回值。
理解Observable
有别于流行的说法,Observable既不像多个EventEmitter
,也不像一种能返回多个值的Promise
。
在一些场合,比如广播消息时,Observer看起来很像EventEmitter
,在RxJS中,被称为Subject
。而在大多数情况下,Observable并不像EventEmitter
。
Observables 像一群没有参数的函数,形成了多个值的集合。
考虑以下情况:
function foo() {
console.log('Hello');
return 42;
}
var x = foo.call(); // same as foo()
console.log(x);
var y = foo.call(); // same as foo()
console.log(y);
输出是:
"Hello"
42
"Hello"
42
用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);
});
上面2种情况其实是由于函数和Observable都是一种惰性的计算。如果你不调用函数,那么console.log('Hello')
就不会被执行,也不会有输出。同样的,只用当“调用”(通过subscribe
订阅)Observable,才会有输出。
此外,调用和订阅都是孤立运行的。2个函数分别被调用会产生2个效果,2个Observable订阅者会产生2个独立的效果。
不像EventEmitter
会派发它的状态并且不论是否有订阅者都会执行那样,Observable不会派发状态而且是惰性的。
订阅observable,类似于调用一个函数
有些声音宣称Observable是异步的,这是不对的。如果你使用一个函数来输出日志,像这样:
console.log('before');
console.log(foo.call());
console.log('after');
输出是:
"before"
"Hello"
42
"after"
同样的行为,使用Observable:
console.log('before');
foo.subscribe(function(x){
console.log('Hello');
return x;
});
console.log('after');
输出是一样的:
"before"
"Hello"
42
"after"
以上证明了订阅foo
之后,效果和函数一样,都是同步的。
无论是同步方式还是异步方式,obsverable都可以择其一来传递返回值。
Observable和函数之间有什么区别?Observables可以随着时间线返回多个值,函数却不能,因此你可以这样:
function foo() {
console.log('Hello');
return 42;
return 100; // dead code. will never happen
}
函数返回单一的值,Observables却可以这样:
var foo = Rx.Observable.create(function(observer){
console.log('hello');
observer.next(42);
observer.next(100);
observer.next(200);
});
console.log('before');
foo.subscribe(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);
observer.next(200);
setTimeout(function(){
observer.next(300);
},1000);
});
console.log('before');
foo.subscribe(function(x){
console.log(x);
});
console.log('after');
输出为:
"before"
"Hello"
42
100
200
"after"
300
结论:
func.call()
意味着“同步的返回一个值”。observable.subscribe()
意思是“返回任意数量的值,同步式、异步式二择其一。”
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。