[英]Angular: Which is the best way of refactoring the code inside ".subscribe()"
假设我有这样的组件
原始代码:
import { HttpClient } from '@angular/common/http';
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `<pre>{{ response | json }}</pre>`,
styleUrls: ['./app.component.css'],
})
export class AppComponent {
constructor(private _http: HttpClient) {
this.fetchUsers();
}
response!: any;
fetchUsers() {
this._http.get(`https://jsonplaceholder.typicode.com/users`).subscribe(
(resp) => {
console.log(resp);
this.response = resp;
},
(err) => {
console.error(err);
this.response = err;
},
() => {
console.log('Subscription Complete');
}
);
}
}
我有以下方法来重构上面的代码......
重构方法一:
import { HttpClient } from '@angular/common/http';
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `<pre>{{ response | json }}</pre>`,
styleUrls: ['./app.component.css'],
})
export class AppComponent {
constructor(private _http: HttpClient) {
this.fetchUsers();
}
response!: any;
onSubscribe = (resp: any) => {
console.log(resp);
this.response = resp;
};
onError = (err: any) => {
console.error(err);
this.response = err;
};
onCompletion = () => {
console.log('Subscription Complete');
};
fetchUsers() {
this._http
.get(`https://jsonplaceholder.typicode.com/users`)
.subscribe(this.onSubscribe, this.onError, this.onCompletion);
}
}
重构方法 2:
import { HttpClient } from '@angular/common/http';
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `<pre>{{ response | json }}</pre>`,
styleUrls: ['./app.component.css'],
})
export class AppComponent {
constructor(private _http: HttpClient) {
this.fetchUsers();
}
response!: any;
onSubscribe(resp: any) {
console.log(resp);
this.response = resp;
}
onError(err: any) {
console.error(err);
this.response = err;
}
onCompletion() {
console.log('Subscription Complete');
}
fetchUsers() {
this._http.get(`https://jsonplaceholder.typicode.com/users`).subscribe(
(resp) => this.onSubscribe(resp),
(err) => this.onError(err),
() => this.onCompletion()
);
}
}
重构方法 3:
import { HttpClient } from '@angular/common/http';
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `<pre>{{ response | json }}</pre>`,
styleUrls: ['./app.component.css'],
})
export class AppComponent {
constructor(private _http: HttpClient) {
this.fetchUsers();
}
response!: any;
fetchUsers() {
this._http.get(`https://jsonplaceholder.typicode.com/users`).subscribe({
next: (resp: any) => {
console.log(resp);
this.response = resp;
},
error: (err: any) => {
console.error(err);
this.response = err;
},
complete: () => {
console.log('Subscription Complete');
},
});
}
}
重构方法 4:
import { HttpClient } from '@angular/common/http';
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `<pre>{{ response | json }}</pre>`,
styleUrls: ['./app.component.css'],
})
export class AppComponent {
constructor(private _http: HttpClient) {
this.fetchUsers();
}
response!: any;
onSubscribe = (resp: any) => {
console.log(resp);
this.response = resp;
};
onError = (err: any) => {
console.error(err);
this.response = err;
};
onCompletion = () => {
console.log('Subscription Complete');
};
fetchUsers() {
this._http.get(`https://jsonplaceholder.typicode.com/users`).subscribe({
next: this.onSubscribe,
error: this.onError,
complete: this.onCompletion,
});
}
}
重构方法 5:
import { HttpClient } from '@angular/common/http';
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `<pre>{{ response | json }}</pre>`,
styleUrls: ['./app.component.css'],
})
export class AppComponent {
constructor(private _http: HttpClient) {
this.fetchUsers();
}
response!: any;
onSubscribe(resp: any) {
console.log(resp);
this.response = resp;
}
onError(err: any) {
console.error(err);
this.response = err;
}
onCompletion() {
console.log('Subscription Complete');
}
fetchUsers() {
this._http.get(`https://jsonplaceholder.typicode.com/users`).subscribe({
next: (resp: any) => this.onSubscribe(resp),
error: (err: any) => this.onError(err),
complete: () => this.onCompletion(),
});
}
}
现在的问题是
考虑性能(首先是可读性)——哪个是最好的选择?
- 重构方法 1?
- 重构方法 2?
- 重构方法 3?
- 重构方法 4?
- 重构方法 5?
- 原始代码?
我认为最好的方法是数字 4,原因如下:
谈到可读性,您在订阅中传递三个 arguments 的方式(下一个、错误、完成)实际上已被 RxJS 弃用,因为 function arguments 会导致代码难以阅读。 你可以在这里读更多关于它的内容
相反,RxJS 建议您使用 JS 882829995402888 作为参数,您可以在其中定义不同回调的代码
({next: () =>{}, error: () =>{}, complete: () =>{})
将代码分成函数可以帮助您使其更清晰易读。
谈论性能,如果您将 JS object 之类的参数传递给订阅 RxJS,则将空的 function 传递给其中一个回调,而不是您自己执行。
就个人而言,我会重构为声明式方法
async
pipe。示例服务:
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { tap } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class UserService {
users$ = this.http
.get(`https://jsonplaceholder.typicode.com/users`)
.pipe(tap((response) => console.log(response)));
constructor(private http: HttpClient) {}
fetchUsers() {}
}
示例组件/模板
import { Component } from '@angular/core';
import { catchError } from 'rxjs';
import { UserService } from './user.service';
@Component({
selector: 'my-app',
template: `<pre>{{ users$ | async | json }}</pre>`,
styleUrls: ['./app.component.css'],
})
export class AppComponent {
errorMessage = '';
users$ = this.userService.users$.pipe(
catchError(err => this.errorMessage = err)
)
constructor(private userService: UserService) { }
}
有关此声明模式的更多信息,请参阅: https://youtu.be/0XPxUa8u-LY
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.