[譯] RxJS文檔02—— Observable 可觀察量

原文:http://reactivex.io/rxjs/manu...html

Observable

可觀察量是一種能惰性推送的集合,他能夠包含多個值。下面的表格對比了推送和拉取2種方式:react

單值 多值
拉取 Function Iterator
推送 Promise Observable

舉例來講,下列Observable 在被訂閱以後會當即推送(同步)值1,2,3,而值4將會在1秒以後被推送到訂閱者,以後這個流進入完成狀態:app

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');

執行以後會輸出:async

just before subscribe
got value 1
got value 2
got value 3
just after subscribe
got value 4
done

pull vs push 拉取 vs 推送

拉取和推送是數據生產者和數據使用者之間進行數據交換的2種形式。函數

什麼是拉取?

在拉取系統中,數據使用者決定什麼時候從數據生產者那裏接收數據。數據生產者自身並不知道數據什麼時候會被傳遞給使用者。lua

每個js函數都是一個拉取系統。函數是一個數據生產者,經過在別處被調用,他返回的單一值將會被投入計算。日誌

ES2015又引入了新的拉取系統,generator和迭代器(function*)。調用iterator.next()來消費從迭代器(數據生產者)中拉取到的數據。code

Producer Consumer
Pull 被動的:被請求的時候返回數據 主動的:決定數據什麼時候被請求
Push 主動的:按照本身的步驟返回數據 被動的:接收的數據後做出反應

什麼是推送?

在推送系統中,數據生產者決定什麼時候把數據推送給使用者,使用者本身並不知道什麼時候可以接收到數據。server

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()意思是「返回任意數量的值,同步式、異步式二擇其一。」

相關文章
相關標籤/搜索