SNS项目笔记<七>--深入探究RXjs

摘要:弄懂本篇文章,首先请看SNS项目笔记<四>--RX简要用法

在正常使用RX做监听的时,时不时有些页面需要重复点击进入,这样在进入该页面的时候,会产生多次触发subscribe方法,这个时候往往会出现多次赋值或者多次提交操作,即浪费资源,也让某些功能直接成为了Bug。于是博主就寻找了一天的源码与探讨了方法,特此记录下来。

1、优化封装provider

在查找出现这样的原因的时候,博主首先认为是单例问题,这里先贴出原来封装好的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 = new Subject()

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

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

这里subject直接为new的一个Subject对象,这样可能造成多次回调问题,于是为了保险起见,我重新整理了自定义单例的代码:

//自定义单例类
export class MySubject extends Subject{
    public static readonly instance:MySubject = new MySubject()
    private constructor(){
            super()
    }
}

这样完成了单例对象的建立,本以为问题得以解决,殊不知还是没有解决重复问题,于是开始翻阅源码

2、RXjs部分源代码

SNS项目笔记<七>--深入探究RXjs_第1张图片
Subject源代码.png

从subject源码上我们难以看出问题,其中有complete()和unsubscribe()供以使用,但是我试了下竟然将所有的监听移除了,这里可以看出并没有写complete()与unsubscribe()的使用情况于是继续深入寻找js源码:

SNS项目笔记<七>--深入探究RXjs_第2张图片
JS源码--complete方法.png
SNS项目笔记<七>--深入探究RXjs_第3张图片
JS源码--unsubscribe方法.png

说明: "this.isStopped" 处理该subject对象是否继续处理事件监听,"this,obervers" 存储监听回调的对象Array,显然在这两个方法一个将数组置空,一个将数组直接赋值为null,并且isStopped状态直接为true。这样整个subscribe系统处于瘫痪状态,需要重新另起Subject对象来完成新的监听动态。

3、重写方法

掌握好其原理后,就好重写方法来完成我们的需求,这里我们先整理下思路:
1、需要时刻保持subject活跃
2、需要在页面pop过后进行解绑其监听以达到不重复情况
3、注意的是在返回pop页面的时候的监听不可取消

于是重构代码:

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 = MySubject.instance

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

    bus(): Observable {
        return this.subject.asObservable();
    }
    
    //公开方法
    complete(){
          this.subject.finish()
    }
}

//自定义单例类
export class MySubject extends Subject{
    public static readonly instance:MySubject = new MySubject()
    private constructor(){
            super()
    }
  
//解除最后一个绑定的observe
finish(){
    if (this.closed) {
            return
        }
    let len = this.observers.length;
    let observers = this.observers.splice(len-1,1);
    }    
}

在page里面调用生命周期方法:

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

这样便完成了只有一次回调了

你可能感兴趣的:(SNS项目笔记<七>--深入探究RXjs)