【问题标题】:Cancel a HTTP request inside an Observable.create在 Observable.create 中取消 HTTP 请求
【发布时间】:2016-07-05 00:19:43
【问题描述】:

我正在使用 Angular 2 rc3。

我有一个服务,它返回一个 rxjs Observable,其中有一些异步任务,然后是一个递归 HTTP 请求。它是分块上传,因此有多个顺序请求,每个请求都在前一个块的成功处理程序中触发。

我想知道在处置包含 Observable 时如何取消内部 HTTP 请求。

这基本上就是我正在做的事情(不是真正的代码):

// UploadService

upload (file) {
    return Observable.create((observer) => {

        let reader = new FileReader();

        // convert file into chunks
        let chunkedFile = this.chunkFile(file);

        reader.onloadend = (event) => {

            // THIS IS THE REQUEST I WANT TO CANCEL
            this.http.put('url/to/upload/to', chunkedFile.currentChunk)
                .subscribe((res) => {

                    // emit some data using containing observable, e.g. progress info
                    observer.next(res);

                    // trigger upload of next chunk
                    this.uploadFileInChunks(reader, chunkedFile, observer);

                });
        };

        // this triggers the onloadend handler above
        this.uploadFileInChunks(reader, chunkedFile, observer);
    });
}

然后我像这样在我的组件中使用它:

// ExampleComponent

upload () {
    this.uploader = this.uploadService.upload(file)
        .subscribe((res) => {
            // do some stuff, e.g. display the upload progress
        })
}

ngOnDestroy () {
    // when the component is destroyed, dispose of the observable
    this.uploader.dispose();
}

我可以在网络面板中看到,销毁组件后,上传进度仍在继续。

如何取消?

如果它有助于理解上传,那么我正在使用这个移植到 Angular 2 的 https://github.com/kinstephen/angular-azure-blob-upload

【问题讨论】:

    标签: angular rxjs


    【解决方案1】:

    您需要在可观察的创建回调中返回一个函数。调用dispose方法时会调用该函数:

    return Observable.create((observer) => {
      (...)
    
      return () => {
        // code to dispose / cancel things 
      };
    });
    

    要在uploadFileInChunks 方法中取消请求,您需要保存订阅并调用其unsuscribe 方法。

    reader.onloadend = (event) => {
      // THIS IS THE REQUEST I WANT TO CANCEL
      this.subscription = this.http.put('url/to/upload/to', chunkedFile.currentChunk)
             .subscribe((res) => {
               // emit some data using containing observable, e.g. progress info
               observer.next(res);
    
               // trigger upload of next chunk
               this.uploadFileInChunks(reader, chunkedFile, observer);
    
             });
    };
    
    () => {
      if (this.subscription) {
        this.subscription.unsubscribe();
      }
    }
    

    【讨论】:

    • 啊哈,我忘记了返回功能-谢谢!顺便说一下,在原始 observable 上调用 dispose 给我带来了错误,我也不得不在那里使用 unsubscribe
    • 仅供参考:处置是 rxjs4,取消订阅是 rxjs5。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-19
    • 2018-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多