【问题标题】:Forkjoin on SwitchMap not returning after subscription订阅后 SwitchMap 上的 Forkjoin 未返回
【发布时间】:2017-11-12 02:54:58
【问题描述】:

我正在编写一个 Observable,它将从服务器获取用户,并试图通过仅获取唯一用户然后缓存它们来提高性能。一旦所有用户都返回,我还使用 forkjoin 更新用户数组。

首先我使用服务调用从服务器获取用户:

getUsersById(user_ids: number[]): Observable<User[]> {
  return Observable.forkJoin(user_ids.map(x => this.getUserById(x)));
}

这使用以下函数返回对象的可观察对象,具体取决于对象是否存在于缓存中或是否需要从服务器中检索。

public getUserById(user_id: number): Observable<User> {
  let tmpUser = this.users.find(x => x.id == user_id);
  if (tmpUser != null) {
    return Observable.of(tmpUser);
  } else {
    // Get Token From Cognito Session
    return this.cognito.getIdToken()
      .flatMap(token => {
      // Convert token into Header and retrieve from server
      let headers = this.getAuthHeader(token);
      return this.http
        .get(`${this.userURL}/${user_id}`, {headers: headers})
        .map((response) => response.json())
        .map(result => {
          let newUser = new User();
          newUser.deserialize(result);
          this.users.push(newUser);
          return newUser;
          });
      });
   }
}

调用该服务的组件上的代码如下:

ngOnChanges() {
  if(this.reports.length != 0) {
    // Get users for reports
    let users = this.reports.map(
      x => {
        return x.user_id;
      });
    // Get unique users
    let uniqueUsers = users.filter(function (item, i, ar) {
      return ar.indexOf(item) === i;
    });
    // Make call (ForkJoin) and wait for all to return
    this.userService.getUsersById(uniqueUsers).subscribe(
      users => {
        // Add users to user array
        this.users = this.reports.map(report => {
          return users.find(user => user.id === report.user_id);
        });
        this.reportsUpdate.emit(this.reports);
      }, err => {
        console.log(err);
      });
  }
}

我遇到的问题是 ForkJoin 永远不会返回,即使我可以验证 getUserById 调用正在运行完成并返回一个值。我很困惑,尽管我不完全确定它们的区别,但我已经尝试了 switchmap 和 flatmap。

** 编辑 **

getIdToken 的代码如下

public getIdToken(): Observable<string> {
  return Observable.create(
    (observer: Observer<string>) => {
      let cognitoUser = this.getCurrentUser();
      if (cognitoUser != null) {
        cognitoUser.getSession((err, session) => {
          if (err) {
            console.log(err);
            observer.error(err);
          } else {
            if (session.isValid()) {
              observer.next(session.getIdToken().getJwtToken());
            }
          }
        });
      } else {
        observer.error('Failed To Retrieve Id Token');
      }
    });
};

getCurrentUser() {
  return this.getUserPool().getCurrentUser();
}

我已经确认程序确实上线了:

observer.next(session.getIdToken().getJwtToken());

因此,观察者未完成似乎不是问题

【问题讨论】:

  • 问题很可能是this.cognito.getIdToken() observable 没有完成。
  • 我已经更新了关于 cognito 服务内容的帖子,并确认它到达了 observer.next() 行。因此,除非我从那里错误返回,否则这似乎不是问题
  • 刚刚意识到下一次调用可能与完成不同,我已将完整调用添加到 getIdToken 并且它现在似乎正在工作!感谢您将我推向正确的方向以找到答案:)

标签: angular typescript angular-observable


【解决方案1】:

问题出在 cognito.getIdToken() 调用中。我编写了在调用时发出令牌值的可观察对象。问题是 Observable.next() 函数和 Observable.complete() 函数不一样,我在之后添加了调用,它不起作用,如下所示

public getIdToken(): Observable<string> {
  return Observable.create(
    (observer: Observer<string>) => {
      let cognitoUser = this.getCurrentUser();
      if (cognitoUser != null) {
        cognitoUser.getSession((err, session) => {
          if (err) {
            console.log(err);
            observer.error(err);
          } else {
            if (session.isValid()) {
              observer.next(session.getIdToken().getJwtToken());
              observer.complete(); // NEW LINE HERE!!!
            }
          }
        });
      } else {
        observer.error('Failed To Retrieve Id Token');
      }
    });
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-24
    • 2020-03-29
    • 1970-01-01
    • 1970-01-01
    • 2021-04-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多