我有这样的功能,只需用xhr请求上传图片:
public uploadAvatar(avatarFile, callback) {
return new Promise((resolve, reject) => {
let formData: any = new FormData();
let url = 'avatar';
let imgArr = "avatar";
let xhr = new XMLHttpRequest();
formData.append(imgArr, avatarFile, avatarFile.name);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
resolve(JSON.parse(xhr.response));
callback('success');
} else {
reject(xhr.response);
callback('error');
}
}
};
xhr.open("POST", environment.baseUrl + url, true);
xhr.setRequestHeader('Auth', this._auth.getToken());
xhr.send(formData);
});
}
如何返回Observable insted Promise?
答案 0 :(得分:2)
这样的事情应该有效
public uploadAvatar(avatarFile, callback) {
return Rx.Observable.create(function (observer) {
let formData: any = new FormData();
let url = 'avatar';
let imgArr = "avatar";
let xhr = new XMLHttpRequest();
formData.append(imgArr, avatarFile, avatarFile.name);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
observer.onNext(JSON.parse(xhr.response));
observer.onCompleted();
callback('success');
} else {
observer.onError(xhr.response);
callback('error');
}
}
};
xhr.open("POST", environment.baseUrl + url, true);
xhr.setRequestHeader('Auth', this._auth.getToken());
xhr.send(formData);
});
}
答案 1 :(得分:2)
eddyP23的答案几乎正确,但还有两件事。
Observables和Promises之间的一个关键区别是,与Promises相比,Observable可以被取消。这与您使用XHR执行AJAX调用的情况非常相关。虽然可以使用abort()
function中止XMLHttpRequest,但您无法中止待处理的Promise。
然而,对于Observables,你可以。当您完成或取消订阅Observable时,您也可以取消XHR对象,因为您知道自己对此不感兴趣。
另请参阅:https://medium.com/@benlesh/promise-cancellation-is-dead-long-live-promise-cancellation-c6601f1f5082
因此,当您使用Promises转换为Observable时,您的函数应如下所示:
public uploadAvatar(avatarFile, callback) {
return Rx.Observable.create(function (observer) {
...
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
observer.onNext(JSON.parse(xhr.response));
observer.onCompleted();
} else {
observer.onError(xhr.response);
}
}
return () => {
xhr.abort();
};
}
)
请注意,我们正在返回一个在处理Observable时使用的函数。有关Observable.create
的更多信息,请查看http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#static-method-create
第二件事是,如果你不关心中止XHR,你可以使用Promises。 RxJS 5以与Observable相同的方式处理Promises。请注意,Observable.from()
将参数ObservableInput
作为参数,详细说明如下:http://reactivex.io/rxjs/class/es6/MiscJSDoc.js~ObservableInputDoc.html
对你而言,这意味着您可以按原样调用uploadAvatar()
,并且返回的Promise将自动转换为Observables:
Observable.from(uploadAvatar(...))
.subscribe(...)
答案 2 :(得分:0)
在你的Promise中使用fromPromise。请记住之前导入该方法,如
import 'rxjs/add/observable/fromPromise';
答案 3 :(得分:0)
简单方法如下:
xhrCall(url, formData, header) {
return Observable.create(function (observer) {
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
observer.next(xhr);
} else {
observer.error(xhr);
}
}
};
xhr.open("POST", url, true);
xhr.setRequestHeader(header.name, header.value);
xhr.send(formData);
});
}