如何在 Angular 2 中取消 HTTPRequest?
Posted
技术标签:
【中文标题】如何在 Angular 2 中取消 HTTPRequest?【英文标题】:How to cancel a HTTPRequest in Angular 2? 【发布时间】:2016-07-29 04:55:30 【问题描述】:我只知道如何拒绝请求承诺。
return new Promise((resolve, reject) =>
this.currentLoading.set(url, resolve, reject);
this.http.get(url, headers: reqHeaders)
.subscribe(
(res) =>
res = res.json();
this.currentLoading.delete(url);
this.cache.set(url, res);
resolve(res);
);
);
【问题讨论】:
【参考方案1】:您可以拨打unsubscribe
let sub = this.http.get(url, headers: reqHeaders)
.subscribe(
(res) =>
res = res.json();
this.currentLoading.delete(url);
this.cache.set(url, res);
resolve(res);
);
sub.unsubscribe();
更多信息在这里:http://www.syntaxsuccess.com/viewarticle/angular-2.0-and-http
【讨论】:
此答案在 beta.15 中不再有效。现在 Observable 中没有unsubscribe
方法。
unsubscribe
已替换为 dispose
。
我正在使用 Angular2 的 RC.5,并且存在 unsubscribe
(rxjs 版本 5.0.0-beta.6)。也许它在制造 cmets 后就恢复了?不确定差异来自哪里。
@DawsonToth Angular 2 团队很久没有更新 rxjs,会在 RC6 中更新
什么是退订突然停止取消请求?可能是什么问题?【参考方案2】:
您可以使用以下简单的解决方案:
if ( this.subscription )
this.subscription.unsubscribe();
this.subscription = this.http.get( 'awesomeApi' )
.subscribe((res)=>
// your awesome code..
)
【讨论】:
适用于 Angular 2.4.6 - 这应该是公认的答案 是否可以通过.toPromise()
方法和then()
,catch()
完成?
@SaeedNamati 为什么需要通过 promise 完成?
this.subscription 的类型是什么??
this.subscription 的错字是 Subscription from rxJs。我会将第一行更正为if ( this.subscription && !this.subscription.closed )
,以检查它是否已被取消订阅【参考方案3】:
聚会有点晚了,但这是我的看法:
import Injectable from '@angular/core'
import Http from '@angular/http'
import Observable from 'rxjs/Observable'
import Subscriber from 'rxjs/Subscriber'
@Injectable ()
export class SomeHttpServiceService
private subscriber: Subscriber<any>
constructor(private http: Http)
public cancelableRequest()
let o = new Observable(obs => subscriber = obs)
return this.http.get('someurl').takeUntil(o)
.toPromise() //I dont like observables
.then(res =>
o.unsubscribe
return res
)
public cancelRequest()
subscriber.error('whatever')
这允许您手动取消请求。有时我最终会得到一个可观察的或承诺,它会对页面上的结果进行更改。如果请求是自动启动的(用户没有在 x 毫秒的字段中输入任何内容)能够中止请求是很好的(用户突然再次输入内容)...
takeUntil 也应该使用简单的超时 (Observable.timer) 如果这是您正在寻找的 https://www.learnrxjs.io/operators/filtering/takeuntil.html
【讨论】:
为什么你不喜欢 observables?对于http来说和promise一样,但是也有error和complete @Mick,我认为 clearfix 只是在满足 OP 对承诺的偏好,而不是表达他/她的意见。 #theSpiritOf***【参考方案4】:您可以在 observable 上使用 SwitchMap,这将取消任何先前请求的响应,并且只请求最新的:
https://www.learnrxjs.io/operators/transformation/switchmap.html
【讨论】:
怎么样?能给我们举个例子吗? 这里的例子:angular-2-training-book.rangle.io/handout/http/…【参考方案5】:使用switchMap
[docs],这将取消所有正在进行的请求并仅使用最新的。
get(endpoint: string): Observable<any>
const headers: Observable<url: string, headers: HttpHeaders> = this.getConfig();
return headers.pipe(
switchMap(obj => this.http.get(`$obj.url$endpoint`, headers: obj.headers, params: params ) ),
shareReplay(1)
);
shareReplay 将为任何迟到的订阅者发出最新的值。
【讨论】:
如果您的headers
没有任何可观察的链接,该怎么办。我在单击按钮时进行了 http 调用,但从文档中,我只能在 observable 上使用 switchMap
【参考方案6】:
这是一个很棒的主题,我还有更多信息要提供。我有一个可能会持续很长时间的 API 调用。所以我需要前一个请求以超时取消。我今天才发现我可以在管道函数中添加一个timeout
运算符。一旦超时完成其计数,这将取消之前的 HTTP 请求。
示例...
return this.exampleHttpRequest()
.pipe(
timeout(3000),
catchError(err => console.log(error)
)
【讨论】:
以上是关于如何在 Angular 2 中取消 HTTPRequest?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Angular 4+ 中取消/取消订阅所有挂起的 HTTP 请求