摘要:讓幫我們取消這個不用多說了,主要是采用,在模版本中讓自已去取數據,再自動的取消。使用的操作符管理訂閱思路是使用那些可以讓流發出結束通知的操作符,將其添加到需要管理的流上,讓自動取消訂閱。
使用rxjs時什么時候取消訂閱是我們必須要關心的,這個系列的前面幾篇也提到過,原則是盡量不去手動訂閱流,但手動訂閱終究是無法避免的,今天主要總結下如何適時的取消訂閱。
讓angular幫我們取消這個不用多說了,主要是采用 async pipe,在HTML模版本中讓angular自已去取數據,再自動的取消。
在component中管理subscription思路是,在component中訂閱的流,在合適的生命周期中取消,最常見就是在OnDestroy的時候。兩種方式,第一種組件維護一個subscription,其它的subscription通過add方法添加至這個subscription上,取消的時候調用這個subscription的unsubscribe方法,第二種,組件維護一個subscription數據,取消的時候遍歷數組,調用每一個subscription的unsubscribe方法。
假設我們有一個服務,可以發送websocket的請求,處理請求的錯誤,同時還可以提供一些公共邏輯的處理,大概像下面這樣:
// service.ts @Injectable() export class MyService { constructor(public websocket: WebsocketService) {} // 發送websocket請求 request(paramObs: Observable): Subscription { return paramObs.subscribe(params => this.websocket.send(params)); } // 處理響應的錯誤 handleError(): Subscribe { return this.websocket.message.pipe( filter(res => res.flag === "request flag") // 取這個上面請求的結果 ).subscribe(res => ...) } // 其它需要在服務中訂閱后處理的邏輯 otherLogic(params: Observable ): Subscription { return params.subscribe(...) } }
第一種思路:
@Component({...}) export class MyComponent implement OnInit, OnDestroy { subscription: Subscription; constructor(private ser: MyService) { } ngOnInit() { this.subscription = this.ser.request(paramsObs1) // 參數是包含請求數據的流 .add(this.otherLogic(paramsObs2)) // 參數是需要處理的數據流 .add(this.ser.handleError()) } ngOnDestroy() { this.subscription.unsubscribe(); } }
第二種思路:
@Component({...}) export class MyComponent implement OnInit, OnDestroy { subscriptions: Subscription[] = []; constructor(private ser: MyService) { } ngOnInit() { this.subscriptions = [ this.ser.request(paramObs1), // 參數是包含請求數據的流 this.ser.handleError(), this.otherLogic(paramsObs2) // 參數是需要處理的數據流 ]; } ngOnDestroy() { this.subscriptions.forEach(sub => sub.unsubscribe()); } }
除了寫法上的不同外,最大的不同在于采用第一種寫法時,你可能需要注意添加的順序,假如例子中的paramsObs2參數流會出完成通知則會導致handleError也被取消掉,這種場景大家可以自己寫個demo試下,第二種寫法則不會,但可能重復去取消一些已經被取消過的流,好在這并不會導致錯誤的發生。
使用rxjs的操作符管理訂閱思路是使用那些可以讓流發出結束通知的操作符,將其添加到需要管理的流上,讓rxjs自動取消訂閱。常用的有下面這些:
take操作符此操作符會上當前流上取指定數量的值,然后發出完成通知,使用只想讓otherLogic處理前3個數據,
ngOnInit() { this.ser.otherLogic(paramsObs2.take(3)); // 不再需要理會訂閱產生的subscription了,處理3個值后自動取消訂閱; }
類似的操作符還有first,from,of等都會發出完成通知。
takeWhile操作符此操作符添加到流上后,每一次發出值時都要檢查操作符中傳入的判定函數返回的結果是否為true,一旦返回false,輸出流將會被取消掉,不再發出值,假設我們的paramsObs2的數據來自于一個formControl:
@Component({ ... template: `` }) export class MyComponent implement OnInit, OnDestroy { control = new FormControl("xxx"); isAlive = true; // 添加一個變量控制流的結束 ... ngOnInit() { ... this.ser.otherLogic(this.control.valueChanges.pipe( takeWhile(() => this.isAlive) // 傳入了一個判定函數 )) } ngOnDestroy() { this.isAlive = false; // 這里變為false; } }takeUntil操作符
此操作符和takeWhile不同,第一,接受的參數不是判定函數,而是Observable, 第二,傳入的observable一旦發出值,輸入流將會被取消訂閱,不管發出的值是true還是fasle,或者是其它值。
@Component({ ... template: `` }) export class MyComponent implement OnInit, OnDestroy { control = new FormControl("xxx"); constructor( ... private router: Router ){} ngOnInit() { ... this.ser.otherLogic(this.control.valueChanges.pipe( takeWhile(this.router.events) // 把router的事件流傳了進去,只要router上有事件發出輸出流就被取消 )) } ... }
這幾種方法各有各有的特點,有的需要額外的變量但用起來簡單粗爆,有的簡潔明了但你需要花心思在其它條件上,在項目中可以根據實際情況選擇最適合的使用。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/97285.html
摘要:好了,今天終于到了你們期待已久的多行新僵尸。好,開始吧上篇鏈接從開始用寫一個命令行小游戲八。多行游戲一開始我為了盡可能簡化游戲,我用了一個單行數組,以模擬只有一行的游戲。一個形如的列表生成式等價于運行后的列表。 好了,今天終于到了你們期待已久的多行+新僵尸。其實我本來想把它們放在兩個beta里解決的,但后來忘了,于是打包起來,跳過beta 5,直接發布了beta 6,就是今天的結束狀態...
摘要:所以一個網,甚至是響應式設計,在兩個平臺上都會損害您整體的。三響應式與如果把網站作為一個單獨的網站,如果網站的內容與桌面版的內容相對缺少,導致用戶回到桌面端的網站,會記錄這種選擇,使搜索排名降低,國內百度就不知道會怎樣。 一、為什么需要響應式設計(responsible web design) 1. 響應式發展背景 1、屏幕尺寸的快速變化,iphone為320x480,分辨率在未來可以...
摘要:前端日報精選精讀與提案知乎專欄第期認識引擎記錄一次利用工具進行性能優化的真實案例簡書中的使用規則教程繼承的實現方法個人文章中文譯組件渲染性能探索個人文章周刊第期表單性能的改進實踐知乎專欄簡單可重用的圖表庫知乎專欄 2017-07-08 前端日報 精選 精讀 TC39 與 ECMAScript 提案 - 知乎專欄【第989期】認識 V8 引擎記錄一次利用 Timeline/Perform...
摘要:響應式命令式這兩種編程風格的思維方式是完全相反的。第二種方式是工人主動去找工人索取生產手機所要的零件,然后生產一臺完整的手機,這兩種方式就對應的響應式和命令式。 angular2中內置了rxjs,雖然框架本身并沒有強制開發者使用響應式風格來組織代碼,但是從框架開發團隊的角度可以看出他們必然是認同這種編程風格的。rxjs本質是基于函數式編程的響應式風格的庫,函數式相對于面向對象來說更加抽...
摘要:好了,廢話少說,繼續吧這一章主要講利用控制用戶登錄。在前面的用戶注冊表單中使用了的響應式表單。在構造函數中聲明了一個對象一個對象和對象對象。并在構造函數中用的方法更新了網頁的標題。接下來導航到下一個頁面,并提示用戶登錄成功。 最近工作比較忙,一直沒有更新文章。原來看別人的文章感覺很過癮,現在自己寫才發現,要堅持下去真的很難。好了,廢話少說,繼續吧!這一章主要講利用angularJs控制...
閱讀 2655·2023-04-26 02:44
閱讀 8254·2021-11-22 14:44
閱讀 2119·2021-09-27 13:36
閱讀 2463·2021-09-08 10:43
閱讀 677·2019-08-30 15:56
閱讀 1392·2019-08-30 15:55
閱讀 2887·2019-08-28 18:12
閱讀 2826·2019-08-26 13:50