Typescript 如何处理axios httpservice可观察响应?
我想我快疯了,因为我对node和typescript还很陌生……我只是想以同步的方式检索http get请求的结果 鉴于:Typescript 如何处理axios httpservice可观察响应?,typescript,axios,nestjs,Typescript,Axios,Nestjs,我想我快疯了,因为我对node和typescript还很陌生……我只是想以同步的方式检索http get请求的结果 鉴于: import { Injectable, HttpService } from '@nestjs/common'; import {} from '@nestjs/core'; @Injectable() export class AppService { private readonly DATA_URL:string = "https://remote/data.
import { Injectable, HttpService } from '@nestjs/common';
import {} from '@nestjs/core';
@Injectable()
export class AppService {
private readonly DATA_URL:string = "https://remote/data.json";
constructor(private httpService:HttpService){}
getSomething(): Array<Object> {
let resp = this.httpService.get(this.DATA_URL); //what do I do now?? It's an observable
}
}
从'@nestjs/common'导入{Injectable,HttpService};
从'@nestjs/core'导入{};
@可注射()
导出类应用程序服务{
私有只读数据\u URL:字符串=”https://remote/data.json";
构造函数(私有httpService:httpService){}
getSomething():数组{
让resp=this.httpService.get(this.DATA_URL);//我现在该怎么办?它是一个可观察的
}
}
编辑:
我在这里写完整的代码,因为它可能对其他学习框架的人有用。我使用了周杰伦的回答,但里奇白也帮助我理解了背后的理论。当然,如果还可以改进/纠正
getSomething(aFilterValue:number): Observable<RespDTO[]> {
return this.httpService.get(this.DATA_URL).pipe(
map((axiosResponse : AxiosResponse) => (axiosResponse.data as
RespDTO[])
.filter((el:RespDTO) => el.aCode===aFilterValue)
.map((el:RespDTO) => ({...el,aDateField:el.aDateField.split('T')[0]}))),
);
}
getSomething(aFilterValue:number):可观察{
返回此.httpService.get(this.DATA\u URL).pipe(
map((axiosResponse:axiosResponse)=>(axiosResponse.data as)
回复[])
.filter((el:RespDTO)=>el.aCode==aFilterValue)
.map((el:RespDTO)=>({…el,aDateField:el.aDateField.split('T')[0]})),
);
}
/**
* A method in your rest controller that relies on the getSomething()
* method as implemented in option 2 below
*/
async showRemoteData() {
const remoteData = await appService.getSomething();
// replace console.log with whatever method you use to return data to the client
console.log(remoteData);
}
原始答案
不能以同步方式从可观察对象检索值。您必须订阅它并在返回值后执行某些操作,或者将其转换为承诺并返回承诺。您的选择包括:
// option 1 change getSomething to doSomething, and do everything in that method
doSomething(): Array<Object> {
let resp = this.httpService.get(this.DATA_URL);
resp.subscribe((value) => { // do something })
}
// option 2 return the observable and subscribe to it outside of that method
getSomething(): Array<Object> {
return this.httpService.get(this.DATA_URL);
}
// outside of the AppService you can use it like this
appService.getSomething().subscribe((value) => {// do something})
// option 3 convert the observable to a promise and return it
getSomething(): Array<Object> {
return this.httpService.get(this.DATA_URL).toPromise();
}
// outside of the AppService you can use it like this
let value = await appService.getSomething();
console.log(value);
//选项1将getSomething更改为doSomething,并使用该方法执行所有操作
doSomething():数组{
让resp=this.httpService.get(this.DATA\uURL);
resp.subscribe((值)=>{//do something})
}
//选项2返回可观察对象并在该方法之外订阅它
getSomething():数组{
返回this.httpService.get(this.DATA\u URL);
}
//在AppService之外,您可以像这样使用它
appService.getSomething().subscribe((值)=>{//do something})
//选项3将可观察到的内容转换为承诺并返回
getSomething():数组{
返回this.httpService.get(this.DATA_URL).toPromise();
}
//在AppService之外,您可以像这样使用它
让value=wait-appService.getSomething();
console.log(值);
在这些选项中,选项3允许您使用async和Wait,这不是同步的,但允许您将async方法中的其余代码视为同步,因此这可能最接近您想要的。我个人认为选项2是你最好的选择,因为你保留了所有可观测的功能,包括所有的操作符。采用javascript中的异步代码,这是解决许多问题的最佳且通常是唯一的解决方案。如果您需要从Nest服务执行此操作,并将结果返回给客户端,您只需返回可观察的,Nest将从那里为您处理订阅。如果需要进行任何额外的数据处理,可以在
可观察的
的.pipe()
操作符之后使用映射
操作符。这方面的一个例子可能是只从axios响应中获取数据,而不是从整个响应中获取数据(这会给JSON.stringify()带来麻烦,因为它本身有循环引用)
下面是这样一个例子
从'@nesjts/common'导入{Injectable,HttpService};
从“axios”导入{AxiosResponse};
从“rxjs”导入{Observable};
从“rxjs/operators”导入{map};
@可注射()
导出类HttpConsumingService{
私有只读数据http://remote/data.json';
构造函数(私有只读http:HttpService){}
callHttp():Observable是一个很好的源代码。如果您更熟悉Promises和async/Wait,那么您也可以将HttpService(以及Axios)与Promises一起使用:
const resp = await this.httpService.get(this.DATA_URL).toPromise(); // Here you get the AxiosResponse object.
const body = resp.data; // Here you get the response body, which is automatically parsed in the .data property of the AxiosResponse.
甚至:
const body = (await this.httpService.get(this.DATA_URL).toPromise()).data;
我使用的是await,但您可以使用经典的promise语法:
this.httpService.get(this.DATA_URL).toPromise()
.then(resp => {
console.log(resp.data);
})
.catch(err => {
// Handle Error Here
console.error(err);
})
您尝试过这个吗?您可以将rxjs可观测值转换为承诺(.toPromise()
)例如,简单地等待它。我很困惑…该代码在后端REST控制器中,由外部API调用。我只想让我的服务器检索数据,过滤数据,最后将其返回到客户端…方法2是否可行?只有一个似乎是3,但不明白为什么在服务器端fr中像nest这样的软件使它变得如此复杂:(我添加了这段代码,这似乎是最好的选择,你能告诉我怎么做吗,从axiosResponse.data开始(这是一个数组)我可以对数组元素做进一步的优化?在我看来,关于可观测性的一件大事是,几乎每个操作符都可以在同一个.pipe()
表达式中进行链接,因此可以在同一个管道中使用多个操作符进行优化