[英]Possible to cancel HttpClient GET request?
I run an internal Angular project that I want to introduce a "Cancel Request" button to. 我运行一个内部Angular项目,想向其中引入“取消请求”按钮。 We have a search function that takes a bunch of parameters, but these requests can take up to two digit amount of seconds (10 and above). 我们有一个带有一堆参数的搜索功能,但是这些请求最多可能需要两位数的秒数(10及以上)。 Usually that happens when someone types something too explicit into the search field, because we do a LIKE/contains search. 通常,当有人在搜索字段中键入过于明确的内容时就会发生这种情况,因为我们进行的是“包含”搜索。
I want to be able to cancel these requests, so my code doesn't execute when returned to the component. 我希望能够取消这些请求,因此返回到组件时我的代码无法执行。 That way, I can quickly cancel the request and send a new one. 这样,我可以快速取消请求并发送新请求。
Right now I set the button to disabled, so the user can't easily send a new request. 现在,我将按钮设置为“禁用”,因此用户无法轻松发送新请求。 If I don't do that, the following problem happens: 如果我不这样做,则会发生以下问题:
Obviously that's not optimal. 显然,这不是最佳选择。
Code to play around with (click the Get stuff
button and a cancel button appears): https://stackblitz.com/edit/angular-cgmyvc 要使用的代码(单击Get stuff
按钮,然后出现取消按钮): https : //stackblitz.com/edit/angular-cgmyvc
To be able to cancel requests you should firstly stop converting observable into Promise and use subscriptions instead. 为了能够取消请求,您首先应该停止将observable转换为Promise,而是使用订阅。
Your service should be: 您的服务应为:
export class TestService {
constructor(private http: HttpClient) { }
public GetStuff() {
return this
.http
.get("https://jsonplaceholder.typicode.com/todos/1")
}
}
Now it returns an observable instead of promise. 现在,它返回一个可观察的而不是应许的。
Then in your component: 然后在您的组件中:
export class AppComponent {
constructor(private service: TestService){}
public request;
public Result;
public GettingStuff = false;
async ngOnInit() {
}
public GetStuff() {
this.GettingStuff = true;
this.request = this.service.GetStuff().subscribe((res) => {
this.Result = JSON.stringify(res);
this.GettingStuff = false;
})
}
public async CancelGettingStuff() {
console.log('cancelled');
this.request.unsubscribe();
this.GettingStuff = false;
}
}
As you see now I put the subscription into a variable request
. 如您现在所见,我将订阅放入变量request
。 If it is necessary to cancel request - we just call an unsubscribe
method. 如果有必要取消请求-我们只需调用一个unsubscribe
方法。 Here is the working stackblitz . 这是工作中的闪电战 。 I recommend to emulate slow internet via developer tools before testing. 我建议在测试之前通过开发人员工具模拟缓慢的Internet。
You will see that request is canceled each time you press cancel
button. 每次按cancel
按钮,您都会看到该请求被取消。
You have to import it like this: 您必须像这样导入它:
import { Subscription } from 'rxjs/Subscription';
EDIT Angular 6 编辑角度6
import { Subscription } from 'rxjs';
import { Component } from '@angular/core';
import { TestService } from './services/test-service';
import { Subscription } from 'rxjs';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
constructor(private service: TestService){}
public Result;
public GettingStuff = false;
res: Subscription;
async ngOnInit() {
}
public async GetStuff() {
this.GettingStuff = true;
this.res = await this.service.GetStuff();
console.log(this.res);
this.Result = JSON.stringify(this.res);
this.GettingStuff = false;
}
public async CancelGettingStuff() {
this.res.unsubscribe();
this.GettingStuff = false;
}
}
Hope this works for you . 希望这对你有用。
You can use switchMap
operator which automatically takes care of unsubscribing from previous observables. 您可以使用switchMap
运算符,该运算符将自动取消订阅先前的可观察对象。
You can refer to this stackblitz 你可以参考这个stackblitz
Not sure if that's doable with promises (probably shouldn't be), but with RxJS and Angular's HttpClient it's as simple as unsubscribing: 不确定是否可以通过promises来实现(可能不应该这样做),但是使用RxJS和Angular的HttpClient就像取消订阅一样简单:
// to send
const requestSubscription = this.httpClient.get(/* ...args */);
// to cancel
requestSubscription.unsubscribe();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.