在Angular Services中使用异步

时间:2018-10-26 17:51:05

标签: angular rxjs angular6

因此,我在下面有两项服务和一项内容。

这是ros.service.ts,它与我的服务器建立了连接

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class RosService {

  // Creates object with the ROS library
  // @ts-ignore <= Makes ts happy, wont error
  ros = new ROSLIB.Ros({
      // Set listen URL for ROS communication
      url : 'ws://localhost:9090'
  });

  initialize() {
      let data;
      // Listens for error from ROS and logs it
      this.ros.on('error', function(error) {
          console.log(error);
      });

      // Find out exactly when we made a connection.
      this.ros.on('connection', function() {
          console.log('Connection made!');
      });
      // Logs when connection is closed
      this.ros.on('close', function() {
          console.log('Connection closed.');
      });
  }
}

// Data is gotten through subscription from each node service
// this.driveControlService.getDriveControlData().subscribe(msg => {
//   this.data = msg;
//   console.log(msg);
// });
// }

接下来,这是一个从服务器子集(或经验丰富的ROS的节点)调用的服务 ms5837.service.ts

import { Injectable } from '@angular/core';
import {BehaviorSubject, Observable} from 'rxjs';
import '../../assets/roslib.js';

@Injectable({
  providedIn: 'root'
})
export class Ms5837Service {
  // Creates object with the ROS library
  // @ts-ignore <= Makes ts happy, wont error
  ros = new ROSLIB.Ros({
    // Set listen URL for ROS communication
    url : 'ws://localhost:9090'
  });
  // Define subject to hold data values
  ms5837: BehaviorSubject<any> = new BehaviorSubject(1);
  // Initializer to be called every time BMP280 is going to be used
  initialize() {
    // Get Data from ROS bmp280 Topic
    // @ts-ignore
    const ms5837Listener = new ROSLIB.Topic({
      ros: this.ros,
      name: '/rov/ms5837',
      messageType: 'ms5837/ms5837_data'
    });

    // Subscribe to bmpListener
    ms5837Listener.subscribe((message) => {
      console.log('Recieved Message on ' + ms5837Listener.name + ' : ' + message);
      // console.log(message);
      this.ms5837.next(message);
    });
  }
  // Define data getter
  getData(): Observable<any> {
    if (this.ms5837) {
      return this.ms5837.asObservable();
    }
  }
}

最后,我尝试获取此组件中的数据并将其分配给数据以供图形使用。 telemetrydata.component.ts

import {OnInit, Component, AfterViewInit} from '@angular/core';
import { Chart } from 'chart.js';
import { Ms5837Service } from '../../../services/ms5837.service';
import { Ms5837Data } from '../../../services/data-models/ms5837.model';

@Component({
  selector: 'app-depth-chart',
  templateUrl: './depth-chart.component.html',
  styleUrls: ['./depth-chart.component.css']
})
export class DepthChartComponent implements OnInit {
    exteriorAltitude = [0];
    seconds = [0];
    name = 'Depth Chart';
    type = 'line';
    data = {
        labels: this.seconds,
        datasets: [{
            label: 'Depth',
            data: this.exteriorAltitude,
            backgroundColor: [
                'rgba(0,188,212, .3)'
            ],
            borderColor: [
                '#00bcd4'
            ],
            borderWidth: 1
            }]
    };
    options = {
        options: {
            responsive: true,
            maintainAspectRatio: false,
            scales: {
                yAxes: [{
                    ticks: {
                        beginAtZero: true
                    }
                }]
            }
        }
    };
    constructor(private ms5837Service: Ms5837Service) {}
    ngOnInit() {
        this.ms5837Service.initialize();
        this.ms5837Service.getData().subscribe((msg: Ms5837Data) => {
            if (msg !== undefined) {
              console.log(msg);
              this.exteriorAltitude.push(msg.altitudeM);
              console.log(this.exteriorAltitude);
              this.seconds.push(msg.header.stamp.secs);
            }
        });
    }
}

当前,与服务器建立连接需要一些时间,因此通过可观察到的遥测数据.component.ts的第一个值是不确定的,从而导致角度崩溃。我尝试使用异步和Promise,但坦率地说,我对rxjs不够熟练。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:0)

我将对此采取行动,希望我的回答会有所帮助。

看来您不需要这两项服务即可完成这项工作...我错了吗?我没有看到您的第二项服务的构造函数,但没有看到您在哪里使用第一项服务。也就是说,我只看第二个服务和组件。

服务

import { Injectable } from '@angular/core';
import {BehaviorSubject, Observable} from 'rxjs';
import '../../assets/roslib.js';

@Injectable({
  providedIn: 'root'
})
export class Ms5837Service {
  ros = new ROSLIB.Ros({
    // Set listen URL for ROS communication
    url : 'ws://localhost:9090'
  });

  // Here I am just returning the observable from ROS

  getData(): Observable<Any> {
    return new ROSLIB.Topic({
          ros: this.ros,
          name: '/rov/ms5837',
          messageType: 'ms5837/ms5837_data'
        });
  }
}

组件

import {OnInit, Component, AfterViewInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';
import { Chart } from 'chart.js';
import { Ms5837Service } from '../../../services/ms5837.service';
import { Ms5837Data } from '../../../services/data-models/ms5837.model';

@Component({
  selector: 'app-depth-chart',
  templateUrl: './depth-chart.component.html',
  styleUrls: ['./depth-chart.component.css']
})
export class DepthChartComponent implements OnInit, OnDestroy {

    // adding a subscsription here
    rosData: Subscription;

    exteriorAltitude = [0];
    seconds = [0];
    name = 'Depth Chart';
    type = 'line';
    data = {
        labels: this.seconds,
        datasets: [{
            label: 'Depth',
            data: this.exteriorAltitude,
            backgroundColor: [
                'rgba(0,188,212, .3)'
            ],
            borderColor: [
                '#00bcd4'
            ],
            borderWidth: 1
            }]
    };
    options = {
        options: {
            responsive: true,
            maintainAspectRatio: false,
            scales: {
                yAxes: [{
                    ticks: {
                        beginAtZero: true
                    }
                }]
            }
        }
    };
    constructor(private ms5837Service: Ms5837Service) {}
    ngOnInit() {

        // this should fire every time the subscription receives a notice
        this.rosData = this.ms5837Service.getData().subscribe((msg: Ms5837Data) => {
            if (msg !== undefined) {
              console.log(msg);
              this.exteriorAltitude.push(msg.altitudeM);
              console.log(this.exteriorAltitude);
              this.seconds.push(msg.header.stamp.secs);
            }
        });
    }

    ngOnDestroy() {
      this.rosData.unsubscribe();
    }
}

答案 1 :(得分:0)

问题神奇地修复了自己(?)所以我想问题解决了。