[英]Using Angular 4 how do I make a http promise call inside of an observable?
如何使用Angular 4在Observable內部進行http promise調用? 我正在使用具有Cognito聯合帳戶的AWS API Gateway。 我們必須使用apigClient.invokeApi對每個http調用進行簽名。 我想獲取promise調用的結果,並以可觀察的方式返回結果。 下面的代碼可以觸發,但根本無法到達其余的可觀察代碼。 當我訂閱可觀察對象時,它永遠不會到達訂閱內部的代碼。 我也沒有任何編譯錯誤。 任何幫助都會有所幫助。
public upload(image, fileType): Observable<FileReturnData> {
const apigClient = apigClientFactory.newClient({
accessKey: this.auth.cognitoAccessKey,
secretKey: this.auth.cognitoSecretKey,
sessionToken: this.auth.cognitoSessionToken,
invokeUrl: this.auth.URL
});
const data = new FileData()
data.image = image;
data.fileType = fileType;
const uploadPromise = apigClient.invokeApi({}, '/users/upload', 'POST', {}, {image: image, fileType: fileType});
const observable = new Observable<FileReturnData>(observer => {
uploadPromise.then(function (uploadResult) {
console.log(uploadResult); // I see this in the console
const fileReturnData = new FileReturnData();
const responseBody = JSON.parse(uploadResult.body);
fileReturnData.filename = responseBody.filename;
console.log('IN OBSERVABLE'); // I never get to this result
observer.next(fileReturnData);
observer.complete();
return () => console.log('upload image user observable disposed');
}).catch(function (uploadImageError) {
return () => console.error(uploadImageError);
});
});
return observable;
}
我只對這樣的Ajax調用使用嵌套的promise,但是我相信您的代碼問題,使用可觀察的對象和嵌套的promise是您過早啟動invokeApi
http調用,對/users/upload
的調用未按預期完成,因此通過upload
返回的observable的訂戶正在等待observer.complete(),這會產生意想不到的后果,因為您正在uploadPromise.then
中調用observer.complete()
, uploadPromise.then
可能已經完成或尚未完成。
看看這是否可以解決您的代碼:
public upload(image, fileType): Observable<FileReturnData> {
const apigClient = apigClientFactory.newClient({
accessKey: this.auth.cognitoAccessKey,
secretKey: this.auth.cognitoSecretKey,
sessionToken: this.auth.cognitoSessionToken,
invokeUrl: this.auth.URL
});
const observable = new Observable<FileReturnData>(observer => {
const data = new FileData()
data.image = image;
data.fileType = fileType;
apigClient.invokeApi({}, '/users/upload', 'POST', {}, {image: image, fileType: fileType})
.then(function (uploadResult) {
console.log(uploadResult); // I see this in the console
const fileReturnData = new FileReturnData();
const responseBody = JSON.parse(uploadResult.body);
fileReturnData.filename = responseBody.filename;
console.log('IN OBSERVABLE'); // I never get to this result
observer.next(fileReturnData);
observer.complete();
}).catch(function (uploadImageError) {
//handle error
});
});
return observable;
}
如果我完全了解您的情況,我個人發現對HTTP調用使用嵌套的Promise比較容易管理。 這是您可以使用的代碼版本,僅使用Promise,然后任何Observable都可以調用upload並等待其完成:
public upload(image, fileType): Promise<FileReturnData> {
const apigClient = apigClientFactory.newClient({
accessKey: this.auth.cognitoAccessKey,
secretKey: this.auth.cognitoSecretKey,
sessionToken: this.auth.cognitoSessionToken,
invokeUrl: this.auth.URL
});
const promise = new Promise<FileReturnData>((resolve, reject) => {
const data = new FileData()
data.image = image;
data.fileType = fileType;
//I moved this "invokeApi" call here because it does not seem like a factory method
//it seems like you start an ajax call when "invokeApi" is called
//so you must keep this all within the promise you are returning to callers
//of the upload function
apigClient.invokeApi({}, '/users/upload', 'POST', {}, {image: image, fileType: fileType})
.then(uploadResult => {
console.log(uploadResult); // I see this in the console
const fileReturnData = new FileReturnData();
const responseBody = JSON.parse(uploadResult.body);
fileReturnData.filename = responseBody.filename;
resolve(fileReturnData);
}, msg => {
reject(msg);
}).catch(ex => {
return () => console.error(ex);
});
});
return promise;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.