Angular 如何在不使用承诺的情况下通过HTTP检索数据
我简化了以下服务代码,以便在此处发布Angular 如何在不使用承诺的情况下通过HTTP检索数据,angular,typescript,promise,observable,ionic4,Angular,Typescript,Promise,Observable,Ionic4,我简化了以下服务代码,以便在此处发布 Load(Channel: any) { // let URL = Globals.AppSiteRoot + Channel.URL return this.LoadData(URL) } Load_Default() { let URL = Globals.AppSiteRoot + "dir1/somedata.XML" console.log(
Load(Channel: any) {
//
let URL = Globals.AppSiteRoot + Channel.URL
return this.LoadData(URL)
}
Load_Default() {
let URL = Globals.AppSiteRoot + "dir1/somedata.XML"
console.log("XYZService.Load_Default------.------>>URL", URL)
//
return this.LoadData(URL)
.then(data => {
{
// do some processing here
console.log("XYZService.Load_Default<<P------.------data", data)
console.log("XYZService.Load_Default<<P------.------This.Data", this.Data)
}
});
}
// https://medium.com/@balramchavan/using-async-await-feature-in-angular-587dd56fdc77
// https://v5.angular.io/api
// https://v5.angular.io/guide/comparing-observables
LoadData(URL: string) { // : Observable<any>
return new Promise(resolve => {
// first argument is URL, put config as second argument
// return this.http.get(URL, {responseType: 'text'})
this.HttpClient.get(URL)
.map(res => res)
.subscribe(
data => {
//
console.log("XYZService.LoadData<<P------.------http.get=>data", data)
// Do some processing here, if needed...
this.Data = data
// return new Observable(this.Data);
resolve(this.Data)
}
,
err => {
// https://forum.ionicframework.com/t/handle-errors-with-http-services/53229
console.log("XYZService.LoadData<<P------.------http:ERR", err)
}
);
});
}
如果我切换到使用async/await我的组件代码会变成这样,我必须承认,一旦接受了await是阻塞的,代码似乎比使用Promise更干净。然后
async ShowV2(Channel: any) {
console.log("XYZComponent.Show------.------>>Channel>>" + Channel.URL)
//
const data = await this.XYZService.Load(Channel)
console.log("XYZComponent------.------>>data", data)
//
this.NavController.parent.select(1)
}
从我读到的许多帖子和博客中,我收到了各种各样的信息
有人说,如果您希望只接收一次数据,请不要使用HttpClient.get.subscribe…,而是使用.toPromise(),但他们从未演示如何处理错误
有人说async/await是唯一一种仍在暗中使用承诺的糖类语法
有人说,可观测到的东西要好得多,甚至角度也广泛使用它们
关于.Load().Load_Default()和component.Show()方法中的代码,这些地方是否需要一个可观察的对象,以及如何对其进行编码
我曾在其他地方使用ReplaySubject(1)从服务广播事件,并在页面之间进行间接通信。然而,我不确定这是另一个使用它的地方
我对事件发射器(如ReplaySubject(1))的典型关注,尤其是几个月后我访问代码时
1) 我如何确保我只订阅了一次活动?在哪里
2) 我退订了吗?在哪里
顺便说一句,尽管我使用的是承诺、可观察、重放主题(1)对我来说都是中国式的,这是一个让我分心和沮丧的巨大来源,我的简单目标是显示我从网络上检索到的一些数据或图片。
因此,如果您有一种方法/模式来清晰地制定代码,那么当我四个月后回来时,一切都是有意义的:)
请包括您将在生产中使用的带有错误处理的模板代码。
感谢您分享您的见解
npm show ionic version
5.4.16
npm show cordova version
9.0.0
npm show angular version
1.7.9
show @angular/core version
9.0.6
ng --version
_ _ ____ _ ___
/ \ _ __ __ _ _ _| | __ _ _ __ / ___| | |_ _|
/ △ \ | '_ \ / _` | | | | |/ _` | '__| | | | | | |
/ ___ \| | | | (_| | |_| | | (_| | | | |___| |___ | |
/_/ \_\_| |_|\__, |\__,_|_|\__,_|_| \____|_____|___|
|___/
Angular CLI: 9.0.4
Node: 10.16.0
OS: win32 x64
Angular: 5.0.3
... common, compiler, compiler-cli, core, forms, http
... platform-browser, platform-browser-dynamic
Ivy Workspace: Yes
Package Version
-----------------------------------------------------------
@angular-devkit/architect 0.900.4 (cli-only)
@angular-devkit/build-optimizer 0.0.35
@angular-devkit/core 9.0.4 (cli-only)
@angular-devkit/schematics 9.0.4 (cli-only)
@schematics/angular 9.0.4 (cli-only)
@schematics/update 0.900.4 (cli-only)
rxjs 5.5.2
typescript 2.8.3
webpack 3.12.0
我建议使用可观察的,而不是承诺,因为角度的使用第一个很多,并在某种程度上促进了反应式风格 考虑以下示例代码:
@Injectable({
providedIn: 'root'
})
export class SomeService {
private readonly URL: string = 'someurl';
constructor(private http: HttpClient) {}
public loadData(): Observable<any> {
return this.http.get(this.URL).pipe(
// if you want to handle errors you can use the catchError operator
// however, a better way is to use a HTTP Interceptor instead
// if you want to see how you can handle errors with the interceptor let me
// know
catchError(error => throwError(error)),
map(res => // do some transformation if you need),
tap(res => // add some side effects if you need)
// don't subscribe in the service - it is considered to be a bad practice
}
}
我建议使用可观察的,而不是承诺,因为角度的使用第一个很多,并在某种程度上促进了反应式风格 考虑以下示例代码:
@Injectable({
providedIn: 'root'
})
export class SomeService {
private readonly URL: string = 'someurl';
constructor(private http: HttpClient) {}
public loadData(): Observable<any> {
return this.http.get(this.URL).pipe(
// if you want to handle errors you can use the catchError operator
// however, a better way is to use a HTTP Interceptor instead
// if you want to see how you can handle errors with the interceptor let me
// know
catchError(error => throwError(error)),
map(res => // do some transformation if you need),
tap(res => // add some side effects if you need)
// don't subscribe in the service - it is considered to be a bad practice
}
}
如果您使用的是角度,那么您应该使用可观察的:它确实是框架的基石部分。你的问题太宽泛,基于观点,无法给出真正的答案。第一件事:不需要取消HTTP呼叫的订阅,它们会在响应后完成。你的问题会涉及很多主题和很多你似乎不确定的事情。你能把它归结为一两个你需要帮助的明确问题吗?仅供参考,
async/await
依赖承诺。只有当异步操作基于承诺时,它们才起作用。因此,async/await
只是使用承诺的一种不同语法,它有时可以使代码更易于编写/理解。您不能使用async/await
代替承诺。您使用async/await
而不是。然后()
使用try/catch
围绕async/await
而不是。catch()
。如果您使用Angular,您应该使用Observable:它确实是框架的基石部分。你的问题太宽泛,基于观点,无法给出真正的答案。第一件事:不需要取消HTTP呼叫的订阅,它们会在响应后完成。你的问题会涉及很多主题和很多你似乎不确定的事情。你能把它归结为一两个你需要帮助的明确问题吗?仅供参考,async/await
依赖承诺。只有当异步操作基于承诺时,它们才起作用。因此,async/await
只是使用承诺的一种不同语法,它有时可以使代码更易于编写/理解。您不能使用async/await
代替承诺。您使用async/await
而不是。然后()
,并在async/await
周围使用try/catch
而不是。catch()
。感谢您提供了代码,请使用示例代码补充您的答案,说明如何调用.loadData()现在,从组件返回一个可观察的对象,以及在服务不需要与GUI/用户交互的情况下,您将如何处理该级别的错误。谢谢。是的,请演示如何使用此http侦听器。我在VSCode/TS接受catchError和tap时遇到困难?地图存在,如果我使用。地图也许你可以显示你的样品在这样一个网站。谢谢。请参阅stackblitz的更新答案。您可以捕获服务中的错误,并触发带有错误消息的警报或障碍栏。关于操作符的使用,你使用的是什么版本的Angular?恐怕我看不到你做了什么,这是我第一次使用stackblitz,我可能已经覆盖了你正在编辑的内容。我想你必须点击“Fork”按钮,并向我发送一个你编辑的唯一链接。在我的package.json中,我仍然使用Angular 5.0.3,因为我被ionic3或Ionic4卡住了,它们一直在变化,我不容易掌握突破性的变化。stackblitz使用的是角度8。我已经在帖子中附加了我的开发配置的版本。如果你能通过stackblitz演示如何阅读这样的跨域资源并将其显示在控制台上,那将是非常棒的。非常感谢您的指导。感谢您提供代码,请您用示例代码补充您的答案,说明您将如何调用.loadData(),现在从组件返回一个可观察值,以及如果服务不希望与GUI/用户交互,您将如何处理该级别的错误。谢谢。是的,请演示如何使用此http侦听器。我在VSCode/TS接受catchError和tap时遇到困难?地图存在,如果我使用。地图也许你可以显示你的样品在这样一个网站。谢谢。请参阅stackblitz的更新答案。您可以捕获服务中的错误并触发警报或警报
providers: [{ provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true }],