【问题标题】:Unsubscribe does not work on RXJS, what is the correct method of use?取消订阅在RXJS上不起作用,正确的使用方法是什么?
【发布时间】:2019-07-27 16:27:19
【问题描述】:

我使用 nativescript-geolocationnativescript-google-maps-sdk 编写了一个代码来监控地图,有一个 Angular 服务将所有访问逻辑封装到 nativescript-geolocation 接收来自 Angular 的评论提供的订阅。

当执行由component.mapViewRead() 函数表示的监听器时,该函数在地图准备就绪时运行,当用户通过将相机位置更改为新坐标,表示 subscripition 的属性被另一个侦听器使用,该侦听器负责通过调用 this.subscription.unsubscribe() 来禁用订阅。

虽然订阅理论上是禁用的并且可以通过this.subscription.isClosed属性输入,但它不会停止处理 Observable 调用。

我做错了吗?还是 RXJS 错误?

下面是服务和组件的代码。

At this link你可以找到服务的完整代码,下面是与问题相关的代码。

startHeadingUpdates() {
        if (this.watchId) {
            return;
        }

        this.watchId = geoLocation.watchLocation(
            (loc) => {
                if (loc) {
this._gpsInfo.next(<GPSInfo>loc);
                }
            },
            (e) => {
                console.error("Error: " + e.message);
            },
            { desiredAccuracy: 3, updateDistance: 10, minimumUpdateTime: 1000 * .3 });
    }
    public get gpsInfo(): Observable<GPSInfo> {
        if (!this._gpsInfo$)
            this._gpsInfo$ = this._gpsInfo.asObservable()
        return this._gpsInfo$;
    }

完整的组件代码可以在at this link找到,下面只有与问题相关的代码:

// componente
    private subscribeGPSInfo() {
        if(this._gpsInfoSubscription && !this._gpsInfoSubscription.isClosed)
            this.unSubscribegpsInfo();

       this._gpsInfoSubscription = this._compass.gpsInfo.subscribe((gpsInfo) => {
            this.gpsInfo = gpsInfo;
        }, (error) => {         console.error("MussalaMapsComponent.ngAfterViewInit() _compass.gpsInfo.subscribe ", error);
        });
    }

    private unsubscribeGPSInfo() {
        if (this._gpsInfoSubscription && this._gpsInfoSubscription.closed) {
        this._gpsInfoSubscription.unsubscribe();
        }
    }

    goToMyLocation() {
        const cfg: GPSConfig = {};
        this._compass.getMyLocation(cfg)
            .then((gpsInfo: GPSInfo) => {
                this.gpsInfo = gpsInfo;
                this.mapView.latitude = this.gpsInfo.latitude;
                this.mapView.longitude = this.gpsInfo.longitude;
            });

        this.subscribeGPSInfo();
    }
    onMapReady(event) {
        const template = this.createInfoWindowTemplate();
        this.mapView.infoWindowTemplates = template;

        let marker: Marker = this._compass.createIslamicMarker(
            1,
            MakerType.MUSSALA,
            "Mussala Fortaleza",
            "Fortaleza, Ce, Brasil",
            "Rua São Paulo, 1831 - Jacarecanga, Fortaleza - CE, 60310-226",
            //-3.7214696,-38.5430259
            <GPSInfo>{ latitude: -3.7214696, longitude: -38.5430259 }
        );
        this.mapView.addMarker(marker);

        marker = this._compass.createIslamicMarker(
            2,
            MakerType.SPONSOR,
            "Curso Arduino Minas",
            "Aquiraz, Ce, Brasil",
            "R. José Alves Pereira, S/N, Aquiraz, CE, Brasil",
            {
                latitude: -3.9242100850690402,
                longitude: -38.45365650951862
            }
        );

        this.mapView.addMarker(marker);

        this.goToMyLocation();
        this.subscribeGPSInfo();

        this.isBusy = false;

    }

更多信息:

 npm list rxjs
IslamicApp@ C:\Users\Admin\workspace\islamic-works\Islamic-App
+-- @angular/cli@8.1.1
| +-- @angular-devkit/architect@0.801.1
| | `-- rxjs@6.4.0
| +-- @angular-devkit/core@8.1.1
| | `-- rxjs@6.4.0
| +-- @angular-devkit/schematics@8.1.1
| | `-- rxjs@6.4.0
| +-- @schematics/update@0.801.1
| | `-- rxjs@6.4.0
| `-- inquirer@6.4.1
|   `-- rxjs@6.5.2  deduped
+-- @nativescript/schematics@0.6.0
| +-- @angular-devkit/core@7.1.4
| | `-- rxjs@6.3.3
| `-- @angular-devkit/schematics@7.1.4
|   `-- rxjs@6.3.3  deduped
+-- @ngtools/webpack@8.0.6
| +-- @angular-devkit/core@8.0.6
| | `-- rxjs@6.4.0  deduped
| `-- rxjs@6.4.0
+-- nativescript-dev-webpack@1.0.1
| `-- @angular-devkit/core@8.0.0
|   `-- rxjs@6.4.0
`-- rxjs@6.5.2

【问题讨论】:

  • 我不确定,但查看您似乎从 2 个不同的地方调用 subscribeGPSInfo() 的代码,您仍然没有检查它是否已被订阅。因此,您可能有多个订阅并且只取消订阅最后一个订阅。
  • 我一次只检查了一个活跃订阅者的代码。每次我运行取消订阅时,它都会注册为“关闭”

标签: angular rxjs nativescript nativescript-angular


【解决方案1】:

我去了您的 Github 链接(现已失效)尝试运行应用程序进行诊断,但它不是应用程序。这是一个代码sn-p。你能设置一个小的示例应用程序吗?这将帮助您更快。

与此同时,您似乎正试图取消订阅this._gpsInfoSubscription,这是this._compass.gpsInfo.subscribe(...)结果

我建议你看看NetanelBasal/ngx-take-until-destroy。使用 rxjs pipengx-take-until-destroy 将有助于更有效地清理内存。我每天在我的 Angular 应用程序中使用它。

【讨论】:

  • Thomas 代码太脏了,还有很多不必要的包,不过我先把它压缩并放到 git 中,等会儿。
  • 另外还有一些敏感数据我现在无法移动。
  • 在我看来,最好的解决方案是检查订阅者是否通过您的订阅关闭,因此它不会执行。在我看来,nx 似乎不是解决方案,因为在此过程中没有任何东西被破坏。只是暂时打断听者,我觉得打个flag会更合适。
猜你喜欢
  • 2020-05-27
  • 2018-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-28
  • 1970-01-01
  • 2018-11-05
相关资源
最近更新 更多