首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >rxjs:如何在可观察到的流中进行条件判断

rxjs:如何在可观察到的流中进行条件判断
EN

Stack Overflow用户
提问于 2020-02-14 12:06:14
回答 1查看 140关注 0票数 1

在我的Angular项目中,我遇到一个案例,如下所示:

在前端我有一个语言系统,用户可以从选项中选择一种语言。每次用户选择一种新语言时,我都需要使用它调用服务器端方法subscribe,如果调用成功,它将返回到subscriptionid

下一次,当用户更改新语言时,我需要创建一个新的订阅。但在此之前,我需要unsubscribe当前的。demo代码如下:

代码语言:javascript
复制
  this.start().subscribe((res) => {
    // store current subscription id   
    this.currentSubscriptionId = res.SubscriptionId;
  });

  private start(): Observable<{ [key: string]: string }> {
      return this.xService.language$.pipe(
          switchMap((language) =>
            this.unsubscribe().pipe(
              switchMap((_) => this.invoke("subscribe",language)) // this.invoke return observable<any>
            )
          )
      );
  }

  private unsubscribe(): Observable<any> {
    if (this.currentSubscriptionId) { // default initial value is empty string  ""
      return this.invoke("Unsubscribe", {
        Id: this.currentSubscriptionId
      });
    } else {
      return of("");
    }
  }

所以我对这个流使用了一个状态变量currentSubscriptionId。它的默认值是空字符串,所以第一次不需要调用unsubscribe方法,返回一个of observable。

在当前的实现中,我将逻辑封装在unsubscribe的函数中,并基于状态变量currentSubscriptionId来处理流程。

对于这种情况,有没有其他优化的解决方案?以一种更具RxJS风格的方式进行这种判断控制。

EN

回答 1

Stack Overflow用户

发布于 2020-02-14 13:01:02

我认为是时候使用"finalize“操作符了,它会在处理订阅时调用给定的函数。

代码语言:javascript
复制
const { Subscription, BehaviorSubject, Observable, of, never, interval } = rxjs;

const Rx = rxjs.operators;

let cleanUp = new Subscription();

function start() {
  return selectedLang.pipe(
    Rx.switchMap(lang => callSubscribeAPI(lang)),
    Rx.switchMap(id =>
      never().pipe(
        Rx.startWith(id),
        Rx.finalize(() => cleanUp.add(callUnsubscribeAPI(id).subscribe()))
      )
    )
  )
}

// Mock of language selection UI:

let selectedLang = new BehaviorSubject("ja");

// Server-side API mocks:

let subscriptionIdCounter = 0;

function callSubscribeAPI(lang) {
  let id = ++ subscriptionIdCounter;
  console.log(`[server] subscribe: ${lang}@${id}`);
  return of(`${id}`);
}

function callUnsubscribeAPI(id) {
  console.log(`[server] unsubscribe: ${id}`);
  return of();
}

// Usage:

start().subscribe(console.log);

interval(300)
 .pipe(Rx.take(4))
 .subscribe(i => 
   selectedLang.next(["en", "kr", "cn", "ja"][i])
 );
代码语言:javascript
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.4/rxjs.umd.min.js"></script>

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60219851

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档