【问题标题】:How to cancel a HTTPRequest in Angular 2?如何在 Angular 2 中取消 HTTPRequest?
【发布时间】:2016-07-29 04:55:30
【问题描述】:

如何在 Angular 2 中取消 HTTPRequest?

我只知道如何拒绝请求承诺。

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);
            }
        );
});

【问题讨论】:

    标签: http promise angular


    【解决方案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 对承诺的偏好,而不是表达他/她的意见。 #theSpiritOfStackOverflow
    【解决方案4】:

    您可以在 observable 上使用 SwitchMap,这将取消任何先前请求的响应,并且只请求最新的:

    https://www.learnrxjs.io/operators/transformation/switchmap.html

    【讨论】:

    【解决方案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)
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-21
      • 2016-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多