Angular 簡介javascript
Angular 由 google 建立,於 2010 年正式發佈,到目前已經更新到 v8.0 版本。相比於目前煊赫一時的 React 與 Vue 框架來講,Angular 自帶完備的生態系統使其更能被稱之爲一款 「 框架 」.前端
Angular 對 typescript 的完美支持(angular 自己就是由 typescript 去編寫的)以及它對模塊化和層次依賴注入的架構方式,使其在構建微服務前端系統也有必定優點. 此外 Angular 框架中引入 Rxjs(ReactiveX javascript) , 運用 Observable 去解決異步問題,使異步問題變的更加簡單和可控。java
Observable (可觀察對象)
社區對於 Observables, Observable, Observer, Subject, Subscription 等有不少介紹,概念性的知識點很難記憶,我概述了幾條,並記錄順便分享一下本身對這些概念的理解:typescript
(1) Observables是Rx的核心, Rx 是(Reactive Extensions)的簡寫,而 rxjs 則是 Observable 在 Javascript 版本的實現,除了 Rxjs, 還有 RxJava, RxDart, RxSwift 等語言的實現版本。
數組
(2) Rxjs 依據 Observable 做爲核心,對可觀察對象 Observable 進行賦能,將其轉換爲操做流,經過 operators 操做符完成對數據流的變換、組合、操縱等。
promise
(3) Observable 是一種新的 push 體系(Pull 和 Push 是兩種不一樣的協議,用於描數據的生產者 和 數據消費者之間的聯繫方式)。能夠經過如下例子簡單加以理解:
bash
function GetName()
{
const name: string = 'i come from a method';
return name;
}
const consumerName: string = GetName(); // consumerName 'i come from a method'
複製代碼
JS 經過調用函數或取數據,此時函數是數據的產生者。函數必須被 call 即調用才能夠被觸發,這就是一種 pull(拉取) 體系。
微信
那麼在 Rxjs 中:架構
import { Observable } from 'rxjs';
const NameObservables$: Observable<string> = new Observable(
subscriber => {
const name: string = 'i come from a method';
subscriber.next(name);
}
);
NameObservables$.subscribe((name: string) => {
console.log(name); // 'i come from a method'
});
複製代碼
代碼中,咱們經過 subscribe 來獲取數據,這和直接調用函數有什麼區別呢?
app
觀察代碼咱們能夠發現,咱們將函數和消費者以前進行了解耦,咱們只是訂閱了數據生產者返回的NameObservables$這個可觀察對象,這使得咱們在獲取原數據的操做上多了一層隔離,利用這層隔離,咱們能夠作不少事,好比利用各類operators對原數據進行各種操做, 而且咱們對一類數據源進行了必定程度的複用,由於任何須要 name 的地方均可以訂閱這個 Observable。
Observable 區別於普通函數的另外一個特色就是,Observable 能夠異步返回多個值,而且因爲上面提到的隔離,咱們能夠針對不一樣的場景分別去處理這些值,只要訂閱 Observable 對象的訂閱者們,均可以獲取到這些數據。大概像這樣:
import { Observable } from 'rxjs';
const NameObservables$: Observable<string> = new Observable(
subscriber => {
const name: string = 'i come from a method';
subscriber.next(name);
const info: any = 'i am happy';
subscriber.next(info);
setTimeout(() => {
const info2: any = 'i like rxjs';
subscriber.next(info2);
}, 2000)
}
);
NameObservables$.subscribe((name: string) => {
console.log(name); // 'i come from a method'
console.log(name); // 'i am happy'
console.log(name); // delay 2s => 'i like rxjs'
});
複製代碼
(4) 可觀察對象 Observable 本質也是基於 訂閱者模式 的一種應用,一個 Observable 構造函數能夠建立任意類型的觀察流供觀察者(Observer)進行訂閱操做。(訂閱?:也就是獲取數據,能夠簡單理解爲訂閱微信公衆號)。生活中咱們經過關注一個公衆號獲取訂閱通知,在 Observable 的世界裏,則經過 訂閱(subscribe)操做去獲取可觀察對象流轉出來的信息。這個過程當中代碼簡單模擬一下以下:
class Observable {
constructor(subscribe){
this.subscriptions = [];
this._subscribe = subscribe;
}
subscribe(observer){
const _this = this;
this.subscriptions.push(observer);
this._subscribe.call(this, observer);
return {
unsubscribe: () => {
const subscriptionIndex = _this.subscriptions.indexOf(observer);
_this.subscriptions.splice(subscriptionIndex, 1);
}
}
}
}
let testObservable$ = new Observable(function(observer){
observer.next(1);
observer.next(2);
observer.next(3);
observer.complete();
});
const subscription = testObservable$.subscribe({
next:function(val){ console.log('next', val); },
error:function(error){ console.log('error', error); },
complete:function(){ console.log('complete'); }
});
// 取消訂閱,再也不接受消息
setTimeout(() => {
subscription.unsubscribe();
}, 2000);
複製代碼
(5) 經過上面的代碼也能夠發現,一個Observer(觀察者) 能獲取到 3 種通知,即 next, error, complete. 當有人訂閱Observable的實例時,須要經過調用 subscribe 方法來獲取到一個 observer對象,subscribe 方法會返回一個 subscription 對象,調用 subscirption 的 unsubscribe 方法, 訂閱者 Observer 就會中止接收通知。原有的Observable對象依然存在。
(6) 結合上面瞭解到的 Observable 特性,咱們能夠對比 Promise體系。熟悉 Promise 的朋友都知道 ,Promise 的 executor 函數接受 resolve, reject 方法,經過調用 resolve 或者 reject 來觸發回調數組,將 resolve 的 data 或者是 reject 的 data 經過回調,返回給 then 方法中的 onFulfilled 函數。Promise 單個體系中,由於這些 value 被回調回去的時間是很是肯定的,因此 promise 也是一種 push 體系, promise 一旦被 resolve 以後便沒法再次返回和取消了,至少他自己不具有取消的能力。下面是 promise 部分簡單的實現:
class Promise {
constructor(executor) {
this.status = PENDING;
this.value = void 0;
this.err = void 0;
this.fulfilledList = new Array(); // fulfilled sub lists
this.rejectedList = new Array(); // rejected sub lists
let resolve = (value) => {
if (this.status === PENDING) {
...
this.fulfilledList.forEach(cb => cb());
}
}
let reject = (err) => {
if (this.status === PENDING) {
...
this.rejectedList.forEach(cb => cb());
}
}
try {
executor(resolve, reject);
} catch (e) {
reject(e);
}
}
then(onFulfilled, onRejected) {
let promiseThen = void 0;
promiseThen = new Promise((resolveNext, rejectNext) => {
....
if (this.status === PENDING) {
this.fulfilledList.push(() => {
...
let result = onFulfilled(this.value);
...
});
this.rejectedList.push(() => {
...
let result = onRejected(this.err);
...
});
}
});
return promiseThen;
}
}
複製代碼
瞭解 Observable 的諸多概念以後,我總結了如下幾點:
(1) Observable 是一種新的 push 體系, 它經過把異步操做封裝成一個能夠自由組合,靈活變化的可觀察對象,來對異步數據流進行控制,是一種高級的 promise。
(2) Observable 是 Rxjs 的核心,真正強大的是 Observable 這種觀察和訂閱模式配合 Rxjs 各種操做符實現對異步流的靈活控制 。
(3) Observable 對比 Promise 擁有可取消,多複用,多值返回, 異步可控等優勢。
(4) Observable 數據源能夠保留,並能夠被多個觀察者使用的特性,使得跨組件的通信變動加簡單。
瞭解了 Observable 的概念及簡單原理,咱們能夠更好的在實際業務場景去使用 Observable 和 Rxjs 。
感謝您的閱讀~