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