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