javascript - 如何中止来自 Observable 的 Ajax 请求?

标签 javascript ajax typescript rxjs observable

我的代码包含我用来将文件上传到我的 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);
    });
}

它是完全可用的,但现在我还想向它添加某种取消机制。

仅仅取消订阅 Observable 是行不通的,因为我需要以某种方式调用 xhr.abort() 否则我会在大量上传中浪费宝贵的资源。

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

最佳答案

当您创建一个 Observable 时,您可以通过从构建器函数返回一个 Subscription 或一个 function 来指定取消订阅行为:

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

关于javascript - 如何中止来自 Observable 的 Ajax 请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38618737/

相关文章:

javascript - Stripe 充电未通过

jquery - 如何让 Chrome 记住 AJAX 表单的密码?

ajax - 通过 ajax 加载时 mediaelement.js 失败

typescript - angular 2 从父组件访问子组件属性

html - 我们如何使用带有自定义控件的 ngFor formArrays?

javascript - 如何在垫表顶部插入新行

javascript - 在 Array.prototype 中获取调用者

javascript - 我无法在 javascript 中将对象从字符串解析为对象

javascript - div inside table td 在右上角?

php - 如何从 MongoDB 集合创建 JSON 提要