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在初始页面加载时触发两次。下面是我调试的过程。有人能解释发生了什么事吗
注意:我在阿波罗频谱聊天中发布了这篇文章,但运气不好,我在底部添加了一个更新
在myngOnInit()
中,我有以下两个查询:
// 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;