微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用switchmap避免Angular中的嵌套订阅?

如何解决如何使用switchmap避免Angular中的嵌套订阅?

我阅读了很多有关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? 任何帮助表示赞赏。

解决方法

这里有很多事情要注意

  1. 看起来像外部可观察的this.sharedSrv.postDetailthis.userSrv.getUserAsObservable()无关。在这种情况下,您还可以使用RxJS forkJoin并行触发可观察对象。由于您要求输入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;
    }
  }
);
  1. 我假设您正在使用async将可观察的对象转换为应许的对象。首先,除非绝对必要,否则我建议您不要将可观察到的东西和承诺混在一起。其次,您可以使用RxJS from函数将可观察对象转换为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()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。