如何将 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)
})
- 使用
HttpParams
添加查询参数 - 这是推荐的(当然,更简洁的)方法
- 如果您需要检查 returned 数据,请专门使用
tap
。但一般来说,您可以在此处添加任何将沿着可观察对象的执行管道执行的操作
- 如果您需要在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
})
)
}
我是 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)
})
- 使用
HttpParams
添加查询参数 - 这是推荐的(当然,更简洁的)方法 - 如果您需要检查 returned 数据,请专门使用
tap
。但一般来说,您可以在此处添加任何将沿着可观察对象的执行管道执行的操作 - 如果您需要在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
})
)
}