如何从Observable中止Ajax请求?

Bla*_*čič 3 javascript ajax observable rxjs typescript

我的代码包含了我用来将文件上传到我的PHP服务器的简单函数(xhr嵌套在一个请求中RxJS/Observable):

fileUpload(file: File): Observable<any> {
    return new Observable( observer => {
        let xhr:XMLHttpRequest = new XMLHttpRequest();
        xhr.onreadystatechange = () => {
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                    observer.next(<any>JSON.parse(xhr.response));
                } else {
                    observer.error(xhr.response);
                    observer.complete();
                }
            }
        };

        xhr.open('POST', '__BACKEND__?action=file-upload', true);
        var formData = new FormData();
        formData.append('file', file, file.name);
        xhr.send(formData);
    });
}
Run Code Online (Sandbox Code Playgroud)

它完全正常,但现在我还想为它添加一些取消机制.

只是取消订阅Observable是行不通的,因为我需要以某种方式打电话xhr.abort()或浪费宝贵的资源与大量上传.

是否可以通过修改此代码来获得优雅的解决方案,或者我做错了因为我正在使用RxJS/Observable这个任务?

pau*_*els 7

创建时,Observable可以通过返回a Subscriptionfunctionfrom构建器函数来指定取消订阅行为:

fileUpload(file: File): Observable<any> {
    return new Observable( observer => {
        let xhr:XMLHttpRequest = new XMLHttpRequest();
        xhr.onreadystatechange = () => {
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                    observer.next(<any>JSON.parse(xhr.response));
                    observer.complete();
                } else {
                    observer.error(xhr.response);
                }
            }
        };

        xhr.open('POST', '__BACKEND__?action=file-upload', true);
        var formData = new FormData();
        formData.append('file', file, file.name);
        xhr.send(formData);

        //Return the tear down logic. 
        //You may also want to check here that it has not already completed
        //Since this gets called in all cases when the `Subscription` terminates
        return () => xhr.abort();
    });
}
Run Code Online (Sandbox Code Playgroud)