我的代码包含我用来将文件上传到我的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
执行此任务?
答案 0 :(得分:7)
创建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();
});
}
答案 1 :(得分:1)
返回xhr对象并在另一个observable中对其执行abort。
var uploadObservable = fileUpload();
var uploadRequest;
uploadObservable.subscribe(
function (x) {
uploadRequest = x;
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
var cancelBtn = Rx.Observable.fromEvent(cancelBtn, 'click');
cancelBtn.subscribe(
function (x) {
uploadRequest.abort();
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
或者
fileUpload()
.flatMap(function(xhr) {
Rx.Observable.fromEvent(cancelBtn, 'click').subscribe(function() {xhr.abort()})
})
.subscribe(...);
答案 2 :(得分:0)
请求将中止进入取消订阅的呼叫。 有关更多详细信息,请参见AjaxObservable.unsubscribe来源: https://github.com/ReactiveX/rxjs/blob/441d52208df8b9247b01f8ca3993e3a7b0870b10/src/internal/observable/dom/AjaxObservable.ts#L423