在订阅之外获取值

Getting values outside the subscribe

我正在尝试使用一些值在图表中显示,但是当我退出订阅函数时,返回的值是未定义的

我已经尝试放入一个对象数组并且仍然认为这是正确的方法,但是同样,当函数退出订阅时,值消失了。

ngOnInit() {
    this.getActiveVulForYear(2019);
    console.log(this.vulYearCount); // Here, all the values are printed correctly
    console.log(this.vulYearCount[1]);// Here, the value printed is undefined
}

getActiveVulForYear(year) {
    for (var i = 0; i <= 11; i++) {
      this.activeVulnerabilitiesByMonth(i, year)
    }
}

activeVulnerabilitiesByMonth(month, year) {
    return this.scanvulService.getScanvuls().pipe(
      map((reports: Scanvul[]) =>
        reports.filter(r => {
          this.arrayVulMonth = new Array()
          this.arrayVulMonth = r.data.split('-')
          return this.arrayVulMonth[1] == month && this.arrayVulMonth[0] == year
        }))).subscribe(
          vulsForYear => {
            this.vulsForYear = vulsForYear
            this.vulYearCount[month] = this.vulsForYear.length;            
          }
    );
}

在某些时候,我用两个参数做了一个对象数组:monthcount。 当我尝试打印计数时,由于某种原因参数为 0。但是当我打印完整数组时,打印件正确显示了所有参数(正确的 countmonth

有人知道如何解决这个问题吗? 谢谢!

不确定你为什么这么说

console.log(this.vulYearCount); // Here, all the values are printed correctly

实际上此时 vulYearCount 应该为空。

当您的 scanvulService.getScanvuls() 提取数据并将其传递到填充数组的管道时,数组 vulYearCount 稍后会被填充。

Observables 是异步执行的,所以如果你想在它们发出一个值或完成时做一些事情(例如记录发出的值),你必须在 subscribe 函数中进行。一个 return 立即 return 一个 Observable 的函数,而不是当 Observable 发出一个值时。您还应该晚点而不是早点订阅。尽可能长时间地使用 Observables,并且只在您真正需要 Observable 的值时订阅,即在 ngOnInit 您想要记录结果的地方。

所以 activeVulnerabilitiesByMonthgetActiveVulForYear 应该 return Observables。在ngOnInit中订阅getActiveVulForYear,并在subscribe函数的模板中记录或设置要绑定到的全局变量。

getActiveVulForYear 目前也导致 this.scanvulService.getScanvuls() 被调用 12 次。如果一次调用 this.scanvulService.getScanvuls() return 的所有数据,而您只想过滤或重新排列 returned 数据,只需获取一次数据,然后 filtermap 相应地。

我认为你的代码应该是这样的:

ngOnInit() {
  getActiveVulForYear(2019).subscribe(vulsForYear => {
    this.vulsForYear = vulsForYear;
    this.vulYearCount = vulsForYear.map(vulsForMonth => vulsForMonth.length);
    console.log(this.vulYearCount);
    console.log(this.vulYearCount[1]);
  })
}

getActiveVulForYear(year: number): Observable<Scanvul[][]> {
  return this.scanvulService.getScanvuls().pipe(
    map((reports: Scanvul[]) => {
      let vulsForYear: Scanvul[][] = Array.from({length: 12}, (v, i) => []);
      reports.forEach(r => {
        let yearMonth = r.data.split('-');
        if (yearMonth[0] == year) {
          vulsForYear[yearMonth[1]].push(r);
        }
      })
      return vulsForYear;
    })
  );
}

getActiveVulnerabilitiesByMonth(month: number, year: number): Observable<Scanvul[]> {
  return this.getActiveVulForYear(year).pipe(map(vulsForYear => vulsForYear[month]));
}

https://stackblitz.com/edit/rxjs-bvksfn