SNS項(xiàng)目筆記<七>--深入探究RXjs

摘要:弄懂本篇文章,首先請(qǐng)看SNS項(xiàng)目筆記<四>--RX簡(jiǎn)要用法

在正常使用RX做監(jiān)聽的時(shí),時(shí)不時(shí)有些頁(yè)面需要重復(fù)點(diǎn)擊進(jìn)入,這樣在進(jìn)入該頁(yè)面的時(shí)候,會(huì)產(chǎn)生多次觸發(fā)subscribe方法,這個(gè)時(shí)候往往會(huì)出現(xiàn)多次賦值或者多次提交操作,即浪費(fèi)資源,也讓某些功能直接成為了Bug。于是博主就尋找了一天的源碼與探討了方法,特此記錄下來(lái)。

1、優(yōu)化封裝provider

在查找出現(xiàn)這樣的原因的時(shí)候,博主首先認(rèn)為是單例問(wèn)題,這里先貼出原來(lái)封裝好的provider:

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class RxBus{

    private param: any;
    private subject: Subject<any> = new Subject()

    setListener(param: any): void {
        this.param= param;
        this.subject.next(param);
    }

    bus(): Observable<any> {
        return this.subject.asObservable();
    }
}

這里subject直接為new的一個(gè)Subject對(duì)象,這樣可能造成多次回調(diào)問(wèn)題,于是為了保險(xiǎn)起見,我重新整理了自定義單例的代碼:

//自定義單例類
export class MySubject extends Subject<any>{
    public static readonly instance:MySubject = new MySubject()
    private constructor(){
            super()
    }
}

這樣完成了單例對(duì)象的建立,本以為問(wèn)題得以解決,殊不知還是沒(méi)有解決重復(fù)問(wèn)題,于是開始翻閱源碼

2、RXjs部分源代碼

Subject源代碼.png

從subject源碼上我們難以看出問(wèn)題,其中有complete()和unsubscribe()供以使用,但是我試了下竟然將所有的監(jiān)聽移除了,這里可以看出并沒(méi)有寫complete()與unsubscribe()的使用情況于是繼續(xù)深入尋找js源碼:

JS源碼--complete方法.png
JS源碼--unsubscribe方法.png

說(shuō)明: "this.isStopped" 處理該subject對(duì)象是否繼續(xù)處理事件監(jiān)聽,"this,obervers" 存儲(chǔ)監(jiān)聽回調(diào)的對(duì)象Array,顯然在這兩個(gè)方法一個(gè)將數(shù)組置空,一個(gè)將數(shù)組直接賦值為null,并且isStopped狀態(tài)直接為true。這樣整個(gè)subscribe系統(tǒng)處于癱瘓狀態(tài),需要重新另起Subject對(duì)象來(lái)完成新的監(jiān)聽動(dòng)態(tài)。

3、重寫方法

掌握好其原理后,就好重寫方法來(lái)完成我們的需求,這里我們先整理下思路:
1、需要時(shí)刻保持subject活躍
2、需要在頁(yè)面pop過(guò)后進(jìn)行解綁其監(jiān)聽以達(dá)到不重復(fù)情況
3、注意的是在返回pop頁(yè)面的時(shí)候的監(jiān)聽不可取消

于是重構(gòu)代碼:

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class RxBus{

    private param: any;
    private subject: MySubject<any> = MySubject.instance

    setListener(param: any): void {
        this.param= param;
        this.subject.next(param);
    }

    bus(): Observable<any> {
        return this.subject.asObservable();
    }
    
    //公開方法
    complete(){
          this.subject.finish()
    }
}

//自定義單例類
export class MySubject extends Subject<any>{
    public static readonly instance:MySubject = new MySubject()
    private constructor(){
            super()
    }
  
//解除最后一個(gè)綁定的observe
finish(){
    if (this.closed) {
            return
        }
    let len = this.observers.length;
    let observers = this.observers.splice(len-1,1);
    }    
}

在page里面調(diào)用生命周期方法:

 ionViewDidLeave(){
    this.rxbus.compelete()
 }

這樣便完成了只有一次回調(diào)了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容