javascript - 订阅循环结束后,Angular 获取响应

标签 javascript java angular rest spring-boot

预先感谢您的宝贵时间。

我正在循环 2 个服务端点来获取数据,我面临的问题是我想等待第一个订阅完成才能循环另一个服务端点,但第一个订阅之外的结果为空如果我将第二个循环放在前一个订阅中,我将面临重复和/或 undefined variable 。

我尝试了两种方法

我尝试的第一个解决方案是循环服务端点,然后在第一个订阅内循环另一个服务端点。这个解决方案的问题是我面临着重复和/或 undefined variable 。

我尝试的第二个解决方案是使用 forkJoin,但我有两个问题。

我使用 forkJoin 遇到的第一个问题是我从后端获取可分页(使用 java - spring boot)来管理分页,所以我无法进行正确的分页,因为 forkJoin 检索数组中的分页,所以详细信息不再有用,因为它在数组中被分割。

我使用 forkJoin 遇到的第二个问题是,每次我再次单击以获取数据时,它都会将结果添加到旧数据中,从而产生无休止的重复(即使我每次按下按钮时将数组设置为空)

我将与大家分享我尝试过的示例以及我正在使用的服务端点

服务1:

getAllQuestionsEvaluation(page: number, level: number, profu: number, idComponent: number): Observable<any> {
    return this.http.get(this.urlEndpoint + 'page/' + page + '/' + level + '/' + profu + '/' + idComponent, {headers: this.headerService.addAuthHeader()}).pipe(
      catchError((e) => {
        this.headerService.serverError(e);
        if (this.headerService.isNoAuth(e)) {
          this.appDialogService.confirm();
        }
        return throwError(e);
      })
    );
  }

我首先循环该端点,然后我需要循环下一个服务的结果以获取其他数据:

服务2:

getAllByIdQuestion(idQuestion: number): Observable<any> {
    return this.http.get(this.urlEndpoint + 'findbyidq/' + idQuestion, {headers: this.headerService.addAuthHeader()}).pipe(
      catchError((e) => {
        this.headerService.serverError(e);
        if (this.headerService.isNoAuth(e)) {
          this.appDialogService.confirm();
        }
        return throwError(e);
      })
    );
  }

我一直在尝试的第一个代码如下,但是我面临重复和结果问题:

jsonComponentsResult 是组件的数组结果,但是该服务没有循环,所以我没有遇到任何问题,这就是为什么我不共享该代码。

this.questions = [];
this.questionsToCompare = [];

for (let com of jsonComponentsResult) {
  this.questionService.getAllQuestionsEvaluation(0, this.evaluation.level, this.evaluation.profu, com.idComponent.idComponent).subscribe(
    (jsonQuestions) => {

      this.questionsToCompare = this.questionsToCompare.concat(jsonQuestions.content);

      for (let i = 0; i < this.questionsToCompare.length; i++) {
        this.questionsGradeService.getAllByIdQuestion(this.questionsToCompare[i].idQuestion).subscribe(
          (response) => {
            this.questionsGrades = this.questionsGrades.concat(response);

            for (let p of this.questionsGrades) {
              if (this.evaluation.idGrade.idGrade === p.idGrade.idGrade) {
                this.questions = this.questions.concat(p.idQuestion);
              }
            }

            this.dataSource = new MatTableDataSource < Questions > (this.questions);
          }
        );
      }



      this.pageIndex = jsonQuestions.number;
      this.pageSize = jsonQuestions.size;
      this.length = jsonQuestions.totalElements;


    },
    (error) => {
      console.log(error);
    }
  );
}

我的第二个解决方案是使用 ForkJoin,但是正如我之前提到的,我无法管理我的分页,并且每次按下按钮时都会收到重复项,即使我将数组设置为空 []:

observables: Observable < Questions > [] = [];
observablePG: Observable < QuestionsGrade > [] = [];

this.questions = [];
this.questionsToCompare = [];
this.questionsGrades = [];

for (let i = 0; i < jsonComponentResult.length; i++) {
  this.observables.push(this.questionService.getAllQuestionsEvaluation(0, this.evaluation.level, this.evaluation.profu, jsonComponentResult[i].idComponent.idComponent));
}
Observable.forkJoin(this.observables).subscribe(
  (response) => {
    for (let x of response) {
      this.questionsToCompare = this.questionsToCompare.concat(x);
    }
    this.observables = [];
    this.getQuestions(this.questionsToCompare);
  },
  (e) => {
    console.log(e);
  }
);

private getQuestions(questionsArray: any) {

  for (let i = 0; i < questionsArray.length; i++) {
    this.observablePG.push(this.questionsGradeService.getAllByIdQuestion(questionsArray[i].idQuestion));

    this.questions = [];
    this.questionsToCompare = [];

  }
  Observable.forkJoin(this.observablePG).subscribe(
    (response) => {

      for (let x of response) {
        this.questionsGrades = this.questionsGrades.concat(x);
      }
      this.observablePG = [];

      for (let p of this.questionsGrades) {
        if (this.evaluation.idGrade.idGrade === p.idGrade.idGrade) {
          this.questions = this.questions.concat(p.idQuestion);
        }
      }

      this.dataSource = new MatTableDataSource < Questions > (this.questions);

    },
    (e) => {
      console.log(e);
    }
  );
}

我想等待第一个订阅完成才能循环另一个订阅,但我一直无法找到解决方案,因为看起来同时循环这些服务会造成麻烦,并且使用 forkJoin,我失去了分页功能,每次按下按钮时我都会再次获得所有列表。

我想获取问题列表,然后获取 questionsGrades 进行比较,是否应该将该问题添加到我的问题数组中。

很抱歉这篇文章很长,感谢您抽出时间。

最佳答案

也许rxjs operator decision tree页面可以帮助您。

第二个,我记得我有一个类似的问题,唯一的区别是第一个 Observable 的值被用作第二个 Observable 中的参数,为此我使用了 switchMap运算符。

关于javascript - 订阅循环结束后,Angular 获取响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56352438/

相关文章:

javascript - 获取所有选中复选框的列表

javascript - Uncaught ReferenceError : function is not defined - Wordpress specific issue

java - java中每分钟的请求数

node.js - 以 Angular 创建新项目时出错

Angular 和 Firebase Cloud Functions 返回 null

javascript - Knockout.js -> 更改 foreach 中的后代绑定(bind)

javascript - ES6 传递函数作为参数示例

JavaFx执行不能在Application类的stop方法没有返回之前完成?

java - JBoss 5.1.0GA "user null is NOT authenticated"问题

Angular 7 单元测试依赖注入(inject)在 ngOnInit 中不起作用