【问题标题】:Reuse the object returned from HTTP response without making another API call in Angular 4重用从 HTTP 响应返回的对象,而无需在 Angular 4 中进行另一个 API 调用
【发布时间】:2023-03-12 19:48:01
【问题描述】:

我正在使用 Promise 在使用 Typescript 的 Angular 4 应用程序中检索 User-Details 对象。

现在,我使用简单的 get 请求在我的应用程序的两个不同位置使用该对象的一部分。像这样的东西:

private _firstName: String;
private _email: String;

  get userDetail(): Promise<any> {
  return this.http
  .get(this._userDetailsURL)
  .toPromise()
  .then((response) => {
    this._firstName = response.json().firstName;
    this._email = response.json().email;
  })
  .catch((err) => err);
  }

  get firstName(): String {
    return _firstName;
  }

  get email(): String {
    return _email;
  }

那么,在 promise 解决后,如何使用它们的 getter 函数检索 firstName 和 email 呢?

我知道我可以重复使用相同的 get() 请求两次,但我不想进行不必要的 api 调用。我想多次检索这些值并进行一次 API 调用。

谢谢

【问题讨论】:

    标签: angular angular-promise angular2-http


    【解决方案1】:

    从 rxjs 5.4.0 开始,您可以使用 shareReplay (https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/sharereplay.md)

    您基本上存储可观察序列并在组件订阅它时返回它。

    // service.ts
    observable$ = this.http
        .get(this._userDetailsURL)
        .map(res => res.json())
        .shareReplay();
    
    getUserDetail(){
        return this.observable$
            .toPromise();
    }
    

    现在当一个组件订阅它时,它将共享相同的 api 请求(不管调用是同时发生还是稍后发生)。这是一个工作 plnkr (https://plnkr.co/edit/drngeofZsXuG9LfJkFob?p=preview) 查看控制台日志以查看 shareReplay 工作。


    更进一步,您可以实现一种清除 shareReplay 的方法。例如,如果用户注销,您可能希望清除用户数据。

    // service.ts
    $observable;
    
    getUserDetail(){
        // if no observable sequence found, create sequence
        if(!this.observable$){
            this.observable$ = this.http
                .get(this._userDetailsURL)
                .map(res => res.json())
                .shareReplay();
        }
    
        return this.observable$
            .toPromise();
    }
    
    clearUserCache(){
        this.observable$ = null;
    }
    

    现在当用户注销时,您可以调用 clearUserCache() 并且当订阅 getUserDetail() 时,将发起另一个 http 请求。

    【讨论】:

      【解决方案2】:

      您可以检查_firstName_email 是否已经存在。如果是这样,只需返回它们,不要调用您的服务器。这样,您就可以随时使用userDetail 方法来获取您的数据。

      private _firstName: String;
      private _email: String;
      
        get userDetail(): Promise<any> {
        if (this._firstName && this._email) {
          return new Promise((resolve, reject) => {
             resolve({firstName: this._firstName, email: this._email})
          })
        }
        return this.http
        .get(this._userDetailsURL)
        .toPromise()
        .then((response) => {
          this._firstName = response.json().firstName;
          this._email = response.json().email;
          return {firstName: this._firstName, email: this._email}
        })
        .catch((err) => err);
        }
      

      【讨论】:

      • 这很好用。但是,在第一个页面加载时从 2 个单独的组件调用 userDetail() 的场景中,API 会被调用两次。有什么解决方案吗?
      猜你喜欢
      • 2020-12-24
      • 1970-01-01
      • 2018-09-12
      • 2018-08-04
      • 2018-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-09
      相关资源
      最近更新 更多