Javascript 不相关的RxJS observable导致阿波罗订阅在ngOnInit上触发多次

Javascript 不相关的RxJS observable导致阿波罗订阅在ngOnInit上触发多次,javascript,angular,rxjs,apollo,Javascript,Angular,Rxjs,Apollo,我有一个音乐应用程序,需要加载一张专辑(我称之为提交)和一个评论部分。我遇到了一个奇怪的问题,当我创建一个comments$observable时,它会导致submission$observable在初始页面加载时触发两次。下面是我调试的过程。有人能解释发生了什么事吗 注意:我在阿波罗频谱聊天中发布了这篇文章,但运气不好,我在底部添加了一个更新 在myngOnInit()中,我有以下两个查询: // to load the submission this.submission$ = this.s

我有一个音乐应用程序,需要加载一张专辑(我称之为提交)和一个评论部分。我遇到了一个奇怪的问题,当我创建一个
comments$
observable时,它会导致
submission$
observable在初始页面加载时触发两次。下面是我调试的过程。有人能解释发生了什么事吗

注意:我在阿波罗频谱聊天中发布了这篇文章,但运气不好,我在底部添加了一个更新

在my
ngOnInit()
中,我有以下两个查询:

// to load the submission
this.submission$ = this.submissionGQL.watch({
  id: this.submissionId
}).valueChanges.pipe(
  takeUntil(this.ngUnsubscribe),
  map(submission => {
    console.log(submission)
    const sub = submission.data.submission;
    sub.releaseDate = moment.utc(moment.unix(parseInt(sub.releaseDate))).format("MMM DD, YYYY");
    sub.proof = new URL(sub.proof || "https://releasehub.co").hostname;
    return sub;
  }),
  shareReplay(1)
);

// to load all the comments for that submission
this.comments$ = this.paginatedCommentsGQL.watch(
  {
    cursor: this.cursor,
    limit: this.limit,
    submissionId: this.submissionId
  }
).valueChanges.pipe(
  takeUntil(this.ngUnsubscribe),
  tap((response) => {
    this.cursor = response.data.paginatedComments.response_metadata.next_cursor;
  }),
  map((response) => {
    return response.data.paginatedComments.comments
  })
)
我在我的HTML中使用异步管道的这些观察值如下:

<ng-container *ngIf="submission$ | async as submission; else loading">
<!-- submission code here -->
</ng-container>

<app-comment *ngFor="let comment of comments$ | async" [comment]="comment"></app-comment>
评论:

query PaginatedComments($cursor: String, $limit: Int, $submissionId: Int) {
    paginatedComments(cursor: $cursor, limit: $limit, submissionId: $submissionId) {
        response_metadata {
          next_cursor
        }
        comments {
            id,
            userID,
            content,
            createdAt,
            user { // single user, aka the commentor
                id,
                username,
                imageURL
            }
        }
    }
}
为了验证我的理论,我从
PaginatedComments
中删除了
user
响应,但这仍然导致缓存重新触发

在下一次测试中,我将
comments$
查询放在页面加载后3秒的
setTimeout
中。有趣的是,这并没有导致
提交$
像页面加载时加载
注释$
那样重新触发。奇怪

我的下一个实验是将
注释$
查询的结果重新配置为
行为主体
,如下所示:

commentsSubject = new BehaviorSubject([]);
comments$ = this.commentsSubject.asObservable();

this.paginatedCommentsQuery.valueChanges.pipe(
  tap((response) => {
    this.cursor = response.data.paginatedComments.response_metadata.next_cursor;
  }),
  map((response) => {
    this.commentsSubject.next(response.data.paginatedComments.comments)
  })
)
执行上述操作以加载注释,不会导致可观察到的
提交$
重新触发。真奇怪。有人有没有想过为什么这篇文章顶部的初始方法会导致
提交$
触发两次?我已经尽了最大的努力调试自己,但我已经达到了我的极限(我想),我可以在我这边调试到什么程度。谢谢

我正在使用阿波罗角度:^1.7.0


更新!因此,我有点理解为什么在我的
map()
管道中执行此操作会导致可观察对象重新触发:

sub.releaseDate = moment.utc(moment.unix(parseInt(sub.releaseDate))).format("MMM DD, YYYY");
sub.proof = new URL(sub.proof || "https://releasehub.co").hostname;
因为我正在更改值…但为什么只有当页面加载中也存在
comments$
时才会发生这种情况?这就是让我困惑的地方。我仍然想知道答案,但现在,我采取了更好的(?)方法,添加了角度
管道
,在我需要的
releaseDate
(releaseDate | formatDate)和
proof
(proof | shortURL)上进行文本转换

sub.releaseDate = moment.utc(moment.unix(parseInt(sub.releaseDate))).format("MMM DD, YYYY");
sub.proof = new URL(sub.proof || "https://releasehub.co").hostname;