如何将 Promise 写成 Observable?

How to write a Promise as an Observable?

我是 Angular 的新手,只是使用 promises,但据我所知我应该使用 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 的方式执行此操作然后点击时(老实说,我不知道是使用点击还是地图等等)但是这里不起作用!我收到错误请求。

感谢您的帮助!

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

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

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

在使用 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

当您必须将多个可观察对象链接在一起时,会使用管道。 看起来您想根据条件在 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)
    })
  1. 使用 HttpParams 添加查询参数 - 这是推荐的(当然,更简洁的)方法
  2. 如果您需要检查 returned 数据,请专门使用 tap。但一般来说,您可以在此处添加任何将沿着可观察对象的执行管道执行的操作
  3. 如果您需要在return发送给订阅者之前以某种方式修改return编辑的数据,请特别使用map。但一般来说,您可以在此处添加其他操作(如果需要的话),这些操作将沿着可观察对象的执行管道执行。您必须 return 来自此运算符的值。
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
            })
        )
}