Angular 为什么我的代码的一部分没有运行,即使它在一个函数中并且上面的print语句可以工作?

Angular 为什么我的代码的一部分没有运行,即使它在一个函数中并且上面的print语句可以工作?,angular,typescript,firebase,loops,google-cloud-firestore,Angular,Typescript,Firebase,Loops,Google Cloud Firestore,我正在运行一个angular项目,该文件将从firebase数据库获取数据,getStatistics函数底部的代码将使用数据库包含的不同访问数据对的信息填充mappairArray 问题是getStatistics函数底部的代码(由反斜杠行表示)将无法运行。嗯,for或if-else循环中不会运行任何内容。但是console.log函数可以工作,所以我不确定为什么代码不能运行。如果我把它放在函数的上面,在所有计算百分比的数学下面,它就会运行 import { Component, OnInit

我正在运行一个angular项目,该文件将从firebase数据库获取数据,getStatistics函数底部的代码将使用数据库包含的不同访问数据对的信息填充mappairArray

问题是getStatistics函数底部的代码(由反斜杠行表示)将无法运行。嗯,for或if-else循环中不会运行任何内容。但是console.log函数可以工作,所以我不确定为什么代码不能运行。如果我把它放在函数的上面,在所有计算百分比的数学下面,它就会运行

import { Component, OnInit } from '@angular/core';

// Firestore imports 
import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument } from '@angular/fire/firestore';
import {Observable,of, from, Timestamp } from 'rxjs';
//import 'rxjs/add/operator/map';
import { map } from 'rxjs/operators';
import * as firebase from 'firebase';
import { NgForm, NgModel } from '@angular/forms';

/*
 getStatistics function:

The goal of this function is to iterate through the database and get the required statistics.
The structure of the database:
  visits IDs are stored as collections, files, in the firestore database.
  Visits of the same ID are stored as documents inside each collection.
The function iterates through each collection, ID,  and counts how many visits are stored in each ID,
 then it increments the AgencyCounter for each agency that was detected in the collection.
The iteration over collections and documents in the database is done by using the "payload.forEach" method

TODO
1. Identify group visits and exclude them from the getStatistics()
2. correct the common pair and common triplet algorithm. Agencies should be sorted based on how many times 
   they appreared in the pair or triplet visits.

 */

interface  Visit{
  code: number;
}

// interface that defines the agency visit structure
interface  AencyVisit{
  AgencyID: string;
  code: string;
  time: Timestamp<any>;
}


@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {

   // Connect Agency to Firebase collection
   visitCollection: AngularFirestoreCollection<Visit>;
   visits: Observable<Visit[]>;

   // Statistics fields
  totalNumVisits = 0;
  totalMultipleVisits = 0;
  highest = 0;
   totalNumPairVisits = 0 ;
   percentageOfPairVisits = 0;
   totalNumTripletVisits = 0;
    percentageOfTripletVisits = 0;
  totalNum5PlusVisits = 0;
  lastHighest = 0;
  percentageOf5PlusVisits = 0;
  totalNum4Visits = 0;
  percentageOf4Visits = 0;
  keyHolder = "";
  valueAdjuster = 0;
  timer = null;
  k = 0;
   commonPairs = new Array();
   commonPair = new Array();
   commonTriplets = new Array();
   commonTriplet = new Array();
   values = new Array();
   //this.values.push(rand = new Array());
   //visitsy = new Array<Observable<Visit[]>>();

   agencyCounterPerID=0;
  //  counterArray ={1:0, 2:0 , 3:0}; //  key represents duplicate or triplet of agencies, value = their number
   // 32 max agency limit per visit - hopefully no one should ever reach this
   counterArray = [0,0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]   
   //pairArray = new Map<Array<Object>, number>(); 
   pairArray = new Map<string, number>(); 
   multiples = 0;
   //  mostCommonPairList and mostCommonTripletList will be used to filter the most common pair and triplet agencies
   mostCommonPairList = {"DEMO-B-Geese":1, "DEMO-A-Berges":1, "DEMO-C1-Gentle":1, "DEMO-C2-Crunke":1,"DEMO-C3-Girls":1, "DEMO-D-Literacy":1, "DEMO-E-Life":1,"DEMO-F-Pools":1};
   mostCommonTripletList = {"DEMO-B-Geese":1, "DEMO-A-Berges":1, "DEMO-C1-Gentle":1, "DEMO-C2-Crunke":1,"DEMO-C3-Girls":1, "DEMO-D-Literacy":1, "DEMO-E-Life":1,"DEMO-F-Pools":1};
   agencyList = new Array(); 
   IDField: Observable<any>;

   // Percentage calculations
   pctMultipleAgencyVisits: number;

  constructor(private afs: AngularFirestore) { }

  ngOnInit(): void {
    // console.log("a");
    this.getStatistics();
  }

  getStatistics(): void{
    const visitArray = this.afs.collection("visits").snapshotChanges();

    visitArray.subscribe(payload => {
      this.totalNumVisits = 0;
      this.totalNumPairVisits = 0;
      this.percentageOfPairVisits = 0;
      this.totalNumTripletVisits = 0;
      this.percentageOfTripletVisits = 0;
      this.totalNum5PlusVisits = 0;
      this.percentageOf5PlusVisits = 0;
      this.totalNum4Visits = 0;
      this.percentageOf4Visits = 0;
      const values = [];



      payload.forEach( item => {
        const visit = item.payload.doc.data() as Visit;
        //const values = [];
        this.totalNumVisits += 1;
        this.timer = null;

        // getting visited frequencies
        const visitedAgencies = this.afs.collection(visit.code.toString()).snapshotChanges();
        visitedAgencies.subscribe(payload => {


          this.agencyCounterPerID = payload.length;
          this.k = 0;
          payload.forEach( item => {
            const agencyVisit = item.payload.doc.data() as AencyVisit; 
            this.agencyList.push(agencyVisit.AgencyID);

            // Add visit pairs to nested list for later analysis
            if (this.agencyCounterPerID == 2){
                if (this.k == 0){
                    this.values.push(new Array(agencyVisit.AgencyID.toString()));
                }

                if (this.k == 1){
                    this.values[this.values.length - 1].push(agencyVisit.AgencyID.toString());
                }

                this.k = 1;
            }
          });

          console.log("list", this.agencyList.toString());

          this.counterArray[this.agencyCounterPerID]+=1;
          if (this.agencyCounterPerID == 2) {
            this.totalNumPairVisits += 1;
            var result2 = this.agencyList.includes(this.agencyList[i]);
            this.mostCommonPairList[this.agencyList[i]] += 1;
          } else if (this.agencyCounterPerID == 3) {
            this.totalNumTripletVisits += 1;
            var result3 = this.agencyList.includes(this.agencyList[i]);
            this.mostCommonTripletList[this.agencyList[i]] += 1;
          } else if (this.agencyCounterPerID == 4) {
            this.totalNum4Visits += 1;
          } else if (this.agencyCounterPerID >= 5) {
            this.totalNum5PlusVisits += 1;
          }

          for (var i=2; i<this.counterArray.length; i++) {
           this.multiples+= this.counterArray[i];
          }

          // percentages
          this.pctMultipleAgencyVisits = this.totalNumVisits / this.counterArray[2];//this.multiples;
          this.totalMultipleVisits = this.totalNumPairVisits + this.totalNumTripletVisits + this.totalNum4Visits + this.totalNum5PlusVisits;
          this.percentageOfPairVisits = this.totalNumPairVisits / this.totalMultipleVisits * 100 ;
          this.percentageOfTripletVisits = this.totalNumTripletVisits / this.totalMultipleVisits * 100;
          this.percentageOf4Visits = this.totalNum4Visits / this.totalMultipleVisits * 100;
          this.percentageOf5PlusVisits = this.totalNum5PlusVisits / this.totalMultipleVisits * 100;
          this.commonPair.push(this.agencyList[0]);
          this.commonPair.push(this.agencyList[1]);
          this.commonTriplet.push(this.agencyList[0]);
          this.commonTriplet.push(this.agencyList[0]);

          this.agencyCounterPerID =0;
          //empty the array
          this.agencyList.length = 0;

        });

    });

  });

    console.log("working");

    /////////////////////////////////////////////////////////////////////////////
    //format pairs into sorted strings
    for (let u = 0; u < this.values.length; u++){
        this.values[u].sort();
        this.values[u].toString();
        console.log("here1");
    }

    //add values to map(dictionary)
    for (let p = 0; p < this.values.length; p++){
        if (this.pairArray.has(this.values[p].toString()) == false){
            this.pairArray.set(this.values[p].toString(), 1);
            console.log("here2");
        }
        else if (this.pairArray.has(this.values[p].toString()) == true){
            //return this.pairArray;
            for (let a = 0; a < 10000; a++){
                if (this.pairArray.get(this.values[p].toString()) == a){
                    this.keyHolder = this.values[p].toString();
                    this.valueAdjuster = a + 1;

                    this.pairArray.delete(this.values[p].toString());
                    console.log("here3");
                }
                console.log("here4");
            }
            this.pairArray.set(this.keyHolder, this.valueAdjuster);
            console.log("here5");
        }
    }

    //find number of occurences of highest frequency pair
    this.highest = 0;
    for (let [key, value] of this.pairArray) {
        console.log("here7");
        if (value > this.highest){
            this.highest = value;
            console.log("here6");
        }
    }

    //add highest frequency pair to list
    for (let [key, value] of this.pairArray) {
        console.log("here9");
        if (value == this.highest && this.commonPairs.indexOf(key) == -1){
            this.commonPairs.push(key);
            console.log("here8");
            //break;
        }
    }

    //find number of occurences of second highest frequency pair
    this.lastHighest = this.highest;
    this.highest = 0;
    for (let [key, value] of this.pairArray) {
        console.log("here11");
        if (value > this.highest && value != this.lastHighest){
            this.highest = value;
            console.log("here10");
        }
    }

    //add second highest frequency pair to list
    for (let [key, value] of this.pairArray) {
        console.log("here13");
        if (value == this.highest && this.commonPairs.indexOf(key) == -1){
            this.commonPairs.push(key);
            console.log("here12");
        }
    }

    // Prints out the dictionary
    for (let [key, value] of this.pairArray) {
        console.log("here14");
        console.log("key: ", key.toString(), ", value: ", value);
    }
    console.log("end run");

    /////////////////////////////////////////////////////////////////////////////

  //console.log("values", this.values);

  // console.log(this.counterArray[1] , " visit for " , 1 , "agencies");
  // console.log(this.counterArray[2] , " visit for " , 2 , "agencies");
  // console.log(this.counterArray[3] , " visit for " , 3 , "agencies");

    //console.log("len", this.values.length);

    //console.log("counter: ", this.counterArray);



    //console.log("cp: ", typeof(this.commonPairs[0]));
    //console.log("v: ", typeof(this.values[0]));
    //console.log("values: ", this.values);

  }

  formatPercent(num) {
    return Math.round(num * 100) / 100;
  }
}

好的,您的代码需要接受很多内容,但看起来底部的for循环是在订阅之外调用的。由于这是异步代码,因此当函数运行时,for循环中的值未定义或为空,因为您从firebase调用中获取的值尚未返回。当您调用subscribe时,代码执行将继续,而另一个线程将等待响应以在subscribe中执行代码