通过返回字符串而不是Angular中的Observable来消除subscription(...)

时间:2019-12-11 16:41:34

标签: angular typescript rxjs observable

已要求我调查如何调用服务,但返回最终结果而不是可观察到的结果。服务中有这样的方法。

getToken(name: string, pass: string): string {
  const url = "https://localhost:44310/api/Security/login";
  const data = { name, pass };

  return this.http.post<any>(url, data);
}

在将要使用它的组件中,我们订阅它并使用结果中弹出的所有内容(或对错误采取行动)。现在,我想介绍一个私有字段,该私有字段在调用 getToken(...)时将读取,并在如果已分配时返回。否则,我想进行POST并存储结果,然后将其返回。

private token: string;

getToken(name: string, pass: string): string {
  if(this.token)
    return this.token;

  const url = "https://localhost:44310/api/Security/login";
  const data = { name, pass };

  this.http.post<any>(url, data)
    .subscribe(
      suc => this.token = suc,
      err => this.token = null);

  return this.token;
}

现在,这显然将失败,因为在离开方法时,尚未为 this.token 异步分配的值。我怀疑是否将它放入这样的成功回调中

this.http.post<any>(url, data)
  .subscribe(
    suc => { this.token = suc; return this.token; }
    err => this.token = null);

会做任何不同的事情。此刻,我陷入困境,开始怀疑无法返回修复,实现的价值消除了组件中的订阅。

有没有办法如上所述介绍一个字段?

我尝试了this post,但产生了错误:“可观察”类型的属性“地图”不存在

1 个答案:

答案 0 :(得分:1)

您不希望从调用堆栈中删除可观察对象。您尚未提供任何理由。在您拥有的异步调用堆栈中,可观察对象要有用得多。

听起来您的实际问题正在缓存结果,因此代码不会重复调用。这很容易做到。

private token: BehaviorSubject<string|null> = new BehaviorSubject<string|null>(null);
private token$ = this.token
  .asObservable()
  .pipe(filter((value) => value != null));

getToken(name: string, pass: string): observable<string> {

  const url = "https://localhost:44310/api/Security/login";
  const data = { name, pass };

  if (this.token.value == null) {
    this.http.post<any>(url, data)
      .subscribe(
        value => this.token.next(value),
        _ => this.token.next(null));
  }

  return this.token$;
}

订户示例:


  someObject.getToken(params)
    .subscribe(token => {
      // when token is available it will not be null.
      // since the source is a BehaviorSubject, we get the last value
    }); 

注意:如果您没有执行UI Pipe Async,请确保取消订阅。

主题参考:

Subject Types

  

我的问题是是否可以通过某种方式对其进行封装并返回一个简单的字符串(如果从以前分配了)或(否则,如果尚未存储该字符串)将执行方法保留在一段时间后返回异步值组件已锁定。

从理论上讲是可以的,但这是一个绝对糟糕的主意:

private token: string | null = null;
getToken(name: string, pass: string): string | observable<string>{

  if (this.token != null) {
    return token;
  }

  const url = "https://localhost:44310/api/Security/login";
  const data = { name, pass };

  return this.http.post<any>(url, data)
      .tap(value => this.token = value);
}

现在,您提供的stringobservable<string>完全可以满足您的要求,但是您的消费者现在必须跳很多圈才能真正完成他们需要做的事情,并且任何读过这篇文章的人都会想到WTF。

订户:


   var result = someobject.getToken(params);
   if (result typeof 'string') {
     dosomethingwithstring(result);
   }
   else {
     result.subscribe(result2 => dosomethingwithstring(result));
   }

这是让其他程序员留下来甚至尝试维护的可怕模式。