【问题标题】:How to write a Promise as an Observable?如何将 Promise 编写为 Observable?
【发布时间】:2021-06-23 16:01:45
【问题描述】:

我是 Angular 的新手,刚接触过 Promise,但据我所知,我应该使用 Observables,但我在这里遇到了一些问题。

所以我承诺执行 GET 请求的代码如下所示:

apiGet(method: any, query: any): Promise<any> {
    return new Promise((resolve, reject) => {
      var otmAPI =
        this.url +
        method +
        "?apikey=" +
        this.API_KEY;
      if (query !== undefined) {
        otmAPI += "&" + query;
      }
      fetch(otmAPI)
        .then(response => response.json())
        .then(data => resolve(data))
        .catch(function(err) {
          console.log("Fetch Error :-S", err);
        });
    });
  }

到目前为止,我的 Observable 方法如下所示:

getPois(method: any, query: any): Observable<any> {
    return this.http.get(this.url +
      method +
      "?apikey=" +
      this.API_KEY).pipe(
        tap(data => {
          console.log(data)
          if (query !== undefined) {
            data += "&" + query;
          }
        })
      );
  }

我不知道我是否做得正确,但它有效,问题是我无法附加查询。 对于我可以附加它的承诺(if-block 将附加查询) 但是,当我尝试使用管道以 Angular 方式执行此操作然后点击时(老实说,我不知道是使用点击还是地图等)但在这里它不起作用!我收到了错误的请求。

非常感谢您的帮助!

【问题讨论】:

    标签: javascript angular typescript promise observable


    【解决方案1】:

    当您必须将多个可观察对象链接在一起时,使用管道。 看起来您想根据条件在 URL 中添加查询参数。 你可以这样做:

    getPois(method: any, query: any): Observable<any> {
        let otmAPI = `${this.url}${method}?apikey=${this.API_KEY}`;
        if (query !== undefined) {
          otmAPI += "&" + query;
        }
        return this.http.get(otmAPI);
      }
    

    然后在你的组件中订阅它:

     this.getPois("method","query").subscribe(res=>{
          console.log('success',res)
        })
    

    【讨论】:

    • 啊,我明白了。好的,所以我以错误的方式使用管道..明白了!非常感谢!这就是我想要的答案:)
    【解决方案2】:
    1. 使用HttpParams 添加查询参数 - 这是推荐(当然,更简洁)的方法
    2. 如果您需要检查返回的数据,请特别使用tap。但一般来说,您可以在此处添加任何将沿着 observable 的执行管道执行的操作
    3. 如果您需要在将返回的数据返回给订阅者之前以某种方式修改返回的数据,请使用map。但一般来说,您在这里添加其他操作(如果您需要的话),这些操作将沿着 observable 的执行管道执行。您必须从此运算符返回一个值。
    getPois(method: any, query: any): Observable<any> {
    
        let options = {
            params: new HttpParams()
                .set('apikey', this.API_KEY)
                .set('someParam', someValue)
                .set('someOtherParam', someOtherValue)
        }
    
        return this.http.get(this.url + method, options)
            .pipe(
                tap(data => {
                    console.log(data);
                }),
                map(data => {
                    let modifiedData = // some modification to data
                    return modifiedData
                })
            )
    }
    

    【讨论】:

      【解决方案3】:

      我建议您使用 HttpClientModule 而不是使用 fetch,因此在您的服务中,您可以执行以下操作来执行 api 请求:

      apiCall() {
          return this.http.get<any>(`url`).toPromise();
        }
      

      httpClient 通常返回一个 Promise,但如果您更喜欢使用 Promise,您可以使用 .toPromise 将结果转换为 Promise。

      在使用 HttpClientModule 之前,您首先必须将其导入您的模块:

      import { NgModule } from '@angular/core';
      import { BrowserModule } from '@angular/platform-browser';
      import { HttpClientModule } from '@angular/common/http';
      
          @NgModule({
            imports: [
              BrowserModule,
              // import HttpClientModule after BrowserModule.
              HttpClientModule,
            ],
            declarations: [
              AppComponent,
            ],
            bootstrap: [ AppComponent ]
          })
          export class AppModule {}
      

      然后您必须将其注入到您的服务中,如下所示:

      import { Injectable } from '@angular/core';
      import { HttpClient } from '@angular/common/http';
      
      @Injectable()
      export class ConfigService {
        constructor(private http: HttpClient) { }
      }
      

      这里有更多详细信息:https://angular.io/guide/http

      【讨论】:

        猜你喜欢
        • 2019-03-22
        • 2021-12-01
        • 2017-04-04
        • 1970-01-01
        • 2017-01-12
        • 1970-01-01
        • 2021-11-10
        • 2020-02-02
        相关资源
        最近更新 更多