问题描述
我阅读了很多有关switchmap及其目的的信息,但是在订阅新数据时我没有看到很多示例。 因此,我在Angular项目中使用了嵌套订阅,我想问一下如何在示例中正确使用switchmap来更好地理解概念。
这是我的嵌套订阅:
this.sharedSrv.postDetail.subscribe(async post => {
if(post) {
this.hasPost = true;
this.post = post;
}
console.log(post);
this.viewedMainComment = null;
this.viewedSubComments = [];
this.userSrv.getUserAsObservable().subscribe(user => {
if(user){
if(this.post.user.id == user.id) this.isOwnPost = true;
this.user = user;
this.postsSrv.getPostInteraction(this.user.id,this.post.id,this.post.user.id).subscribe(interaction => {
this.hasSubscribed = interaction["hasSubscribed"];
this.wasLiked = interaction["wasLiked"];
this.wasdisliked = interaction["wasdisliked"];
this.hasSaved = interaction["hasSaved"];
});
console.log(user);
this.isLoggedIn = true
} else {
this.isLoggedIn = false;
}
})
})
在这里如何正确使用switchmap? 任何帮助表示赞赏。
解决方法
这里有很多事情要注意
- 看起来像外部可观察的
this.sharedSrv.postDetail
和this.userSrv.getUserAsObservable()
无关。在这种情况下,您还可以使用RxJSforkJoin
并行触发可观察对象。由于您要求输入switchMap
,因此可以尝试以下操作
import { of } from 'rxjs';
import { switchMap } from 'rxjs/operators';
this.sharedSrv.postDetail.pipe(
switchMap(post => {
if (post) {
this.hasPost = true;
this.post = post;
}
console.log(post);
this.viewedMainComment = null;
this.viewedSubComments = [];
return this.userSrv.getUserAsObservable();
}),switchMap(user => {
if (user) {
if (this.post.user.id == user.id) this.isOwnPost = true;
this.user = user;
console.log(user);
return this.postsSrv.getPostInteraction(this.user.id,this.post.id,this.post.user.id);
}
return of(null); // <-- emit `null` if `user` is undefined
})
).subscribe(
interaction => {
if(!!interaction) { // <-- only proceed if `interaction` is defined
this.hasSubscribed = interaction["hasSubscribed"];
this.wasLiked = interaction["wasLiked"];
this.wasDisliked = interaction["wasDisliked"];
this.hasSaved = interaction["hasSaved"];
this.isLoggedIn = true;
} else { // <-- set `isLoggedIn` to false if `user` was undefined
this.isLoggedIn = false;
}
}
);
- 我假设您正在使用
async
将可观察的对象转换为应许的对象。首先,除非绝对必要,否则我建议您不要将可观察到的东西和承诺混在一起。其次,您可以使用RxJSfrom
函数将可观察对象转换为Promise。
import { from,of } from 'rxjs';
import { switchMap } from 'rxjs/operators';
const obs$ = this.sharedSrv.postDetail.pipe(
switchMap(post => {
if (post) {
this.hasPost = true;
this.post = post;
}
console.log(post);
this.viewedMainComment = null;
this.viewedSubComments = [];
return this.userSrv.getUserAsObservable();
}),this.post.user.id);
}
return of(null); // <-- emit `null` if `user` is undefined
})
);
from(obs$).then(
interaction => {
...
}
);
,
看起来像你想要的:
this.sharedSrv.postDetail.pipe(
switchMap(post => {
if (post) {
this.hasPost = true;
this.post = post;
}
console.log(post);
this.viewedMainComment = null;
this.viewedSubComments = [];
return this.userSrv.getUserAsObservable();
}),swtichMap(user => {
this.isLoggedIn = false;
if (user) {
if (this.post.user.id == user.id) this.isOwnPost = true;
this.user = user;
this.isLoggedIn = true;
console.log(user);
return this.postsSrv.getPostInteraction(this.user.id,this.post.user.id);
} else {
return of(null);
}
}).subscribe(interaction => {
if (!interaction) return;
this.hasSubscribed = interaction["hasSubscribed"];
this.wasLiked = interaction["wasLiked"];
this.wasDisliked = interaction["wasDisliked"];
this.hasSaved = interaction["hasSaved"];
})
);
,
要转换Observables
,您需要使用piping
,即在可观察对象上调用pipe()
方法,并传递一个rxjs
转换运算符
示例,我们可以将您的代码转换为
this.sharedSrv.postDetail.pipe(
switchMap(post => {
if(post) {
this.hasPost = true;
this.post = post;
}
this.viewedMainComment = null;
this.viewedSubComments = [];
return this.userSrv.getUserAsObservable())
}),switchMap(
user => {
if(user) {
if(this.post.user.id == user.id) this.isOwnPost = true;
this.user = user;
return this.postsSrv.getPostInteraction(this.user.id,this.post.user.id)
} else {
this.isLoggedIn = false;
return of (null) // You need import { of } from 'rxjs'
}
}
)),tap( interaction => {
if(interaction) {
this.hasSubscribed = interaction["hasSubscribed"];
this.wasLiked = interaction["wasLiked"];
this.wasDisliked = interaction["wasDisliked"];
this.hasSaved = interaction["hasSaved"];
}
})
).subscribe()