在Angular2服务中多次进行了HTTP请求
在Angular2服务中多次进行了HTTP请求
我创建了一个可以进行简单GET请求的服务:
private accountObservable = null; constructor(private _http: Http) { } getAccount () { // 如果我们已经缓存了账户信息,就使用缓存中的数据 if (this.accountObservable === null) { this.accountObservable = this._http.get('http://localhost/api/account') .map(res =>res.json().data) .catch(this.handleError); } return this.accountObservable; }
我在我的bootstrap函数中添加了该服务,以便在全局范围内提供它(我希望为所有组件提供相同的实例):
provide(AccountService, { useClass: AccountService })
问题是,当我在不同的组件中调用这个服务时,每次都会进行GET请求。所以,如果我将它添加到3个组件中,即使我检查了observable是否已经存在,也会进行3次GET请求。
ngOnInit() { this._accountService.getAccount().subscribe( account => this.account = account, error => this.errorMessage =error ); }
如何避免多次进行GET请求?
问题出现的原因是因为表单提交和按钮点击被设置为同一个监听器。解决方法是将它们分开设置不同的监听器。
在我的情况下,我遇到了一个问题。当我在Angular2服务中进行HTTP请求时,请求被多次发送。经过排查,我发现问题出现在表单提交和按钮点击的监听器上。原来我将表单提交和按钮点击都设置为了同一个监听器,导致了重复发送请求的问题。
为了解决这个问题,我需要将表单提交和按钮点击分别设置为不同的监听器。这样就可以确保每个事件只触发一次请求。
以下是我在解决问题时的代码示例:
// 设置表单提交的监听器 onFormSubmit() { // 发送HTTP请求的代码 } // 设置按钮点击的监听器 onButtonClick() { // 发送HTTP请求的代码 }
通过将表单提交和按钮点击分开设置监听器,我成功解决了多次发送HTTP请求的问题。现在,每个事件都只会触发一次请求,确保了数据的准确性和一致性。
在Angular2的服务中,发送了多次HTTP请求的问题出现的原因是没有正确地共享Observable对象。解决方法是使用Observable的share()操作符来实现共享。
具体解决方法如下:
1. 在服务中,使用share()操作符来共享Observable对象:
if (this.accountObservable === null) { this.accountObservable = this._http.get('./data/data.json') .share() .map(res => res.json()) .catch(this.handleError); }
2. 在代码中添加引入share()操作符的语句:
import 'rxjs/add/operator/share';
3. 更新到较新的版本的rxjs时,需要使用pipe()方法来实现共享:
.get(...).pipe(share(), map(...))
通过以上方法,可以解决在Angular2服务中多次发送HTTP请求的问题。以上方法经过验证可以正常工作,如果在实际使用中仍然出现问题,请提供能够演示问题的Plunker示例。
参考链接:
- Plunker
这个问题的出现原因是因为在Angular2服务中,每次调用getAccount()
方法时,会导致多次的HTTP请求。这是因为默认情况下,Angular2中的Observables属于Cold Observable类型,每个订阅者会接收到所有的事件(从开始到结束)。为了解决这个问题,需要将Observable转换为Hot Observable类型,即每个订阅者只接收到订阅之后产生的事件。
为了将Observable转换为Hot Observable类型,可以使用Rx的操作符链.publish().refCount()
。在这个问题的例子中,可以使用以下代码来解决问题:
getAccount () { let accountObservable = this._http.get('http://localhost/api/account') .map(res =>res.json().data) .catch(this.handleError); return accountObservable.publish().refCount(); }
但是,这样做是否仍然会导致每次调用getAccount()
方法时发起一个HTTP请求呢?答案是不会的。因为使用了publish().refCount()
操作符链,Observable只会在第一个订阅者订阅时发起HTTP请求,后续的订阅者会共享这个已经发起的请求的结果。
然而,在实际操作中可能会遇到一个错误:Property 'publish' does not exist on type 'Observable
这是因为在Angular2中,没有内置的publish()
方法。要解决这个问题,需要引入Rx库的publish()
方法。可以通过以下方式来引入Rx库:
import 'rxjs/add/operator/publish';
通过引入Rx库后,就可以使用publish()
方法来将Observable转换为Hot Observable类型,解决多次发起HTTP请求的问题。
要解决Angular2服务中多次发起HTTP请求的问题,可以将Observable转换为Hot Observable类型,只需要使用publish().refCount()
操作符链,并引入Rx库的publish()
方法即可。这样就可以确保每个订阅者只接收到订阅之后产生的事件,避免多次发起HTTP请求。