取消Observable.create中的HTTP请求

时间:2016-07-04 16:09:29

标签: angular rxjs

我正在使用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();
}

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

如何取消?

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

1 个答案:

答案 0 :(得分:9)

您需要在可观察的创建回调中返回一个函数。调用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();
  }
}