[英]Async function returning promise, but calling function not resolving
到目前为止,我已经在这里研究了其他类似的项目,但是没有结果,显然需要更好地理解诺言,但是我在这里努力。
我有一个基于Ionic 4 / Angular 8的项目以及基于Azure的后端。 我正在尝试获取页面以显示来自Azure存储的图像,这需要将密钥附加到URL。
为了避免在每个页面中都有'check key,如果过期则获取一个新的key,追加到url'代码,我想我应该做一个服务函数来做到这一点。 但是,尽管我可以使它正常工作,但调用函数似乎并没有在'.then'上等待,因此我无法定义。 (我认为)。 理想情况下,我希望服务仅返回一个字符串
我拥有的服务功能(带有一些注释和调试o / p)是这样的:
// Ideally I'd like to just return a string here ---v
// v- but the async nature needs async return type ??
async getStorageURLWithKey(url: string): Promise<string> {
const nowplus5 = addMinutes(Date.now(), 5); // 5 mins to give some leeway
console.log(nowplus5);
console.log(url);
console.log(this.azurekey);
if (!this.azurekey || isBefore( this.azurekey.Expires, nowplus5 )) {
console.log('Getting new Key');
const keyObj = await this.getAzureKeyServer().toPromise();
await this.saveAzureKeyStore(keyObj);
return url + keyObj.Key; // Return the url with the new Key
} else {
console.log('Key is valid' + this.azurekey.Expires);
const rval = new Promise<string>(function(res) {
res(url + this.azurekey.Key);
});
return rval ; // Key is in time so return it with url
}
}
我的调用函数是这样的:
getBizImg(): string {
console.log('GetBizImg');
if (this.business.Id) { // We have a Business Object
this.userService.getStorageURLWithKey(this.business.ImageURL).then((url) => {
console.log(url);
return url;
}, reject => {
console.log('Rejected:' + reject);
});
} else {
return '';
}
}
如果我从ngOninit调用getBizImg函数,则它将在getBizImg-console.log(url)行之前返回未定义状态。
这是ngOninit:
ngOnInit() {
const imageurl = this.getBizImg();
console.log(imageurl);
}
真正的呼叫应该来自页面:
<ion-content padding>
<ion-img [src]="getBizImg()" ></ion-img>
</ion-content>
但我已对此进行评论,直到我可以解决此问题。 否则,它会陷入看似永无休止的循环。
如果我将getBizImg()转换为异步函数并等待调用并返回诺言,则可以正常工作-如果我将ngInit修改为:
ngOnInit() {
this.getBizImg().then((wibble) => {
console.log(wibble);
});
}
而getBizImg函数可以:
async getBizImg(): Promise<string> {
console.log('GetBizImg ID= ' + this.business.Id);
if (this.business.Id) { // We have a Business Object
const url = await this.userService.getStorageURLWithKey(this.business.ImageURL);
console.log(url);
return url;
} else {
return '';
}
}
但这并不能为我提供HTML所需的简单字符串。
我不确定是否遗漏了(可能)明显的东西...
****编辑更新****我尝试更改为完全异步并包括角度异步管道:
<ion-content padding>
BIZ IMAGE
<ion-img [src]="getBizImg() | async" ></ion-img>
我还尝试仅显示以下字符串: URL is: {{ getBizImg() | async }}
URL is: {{ getBizImg() | async }}
但是它陷入了一个(似乎是无止境的循环)。 但是,这很奇怪,因为它正在访问this.getAzureKeyServer()函数,但是我没有遇到在GetKey API调用中在服务器代码中设置的断点。
这使我走上了另一条路,以更多地检查页面功能。 我拿出了后端的电话,只是返回这样的字符串:
<ion-content padding>
BIZ IMAGE
URL is: {{ getBizImg() | async }}
</ion-content>
async getBizImg(): Promise<string> {
console.log('GetBizImg ID= ' + this.business.Id);
if (this.business.Id) { // We have a Business Object
const url = 'wibble'; // this.business.ImageURL;
// const url = await this.userService.getStorageURLWithKey(this.business.ImageURL);
console.log(url);
return url;
} else {
console.log('invalid id');
return 'invalid id';
}
}
...而且这也陷入了一个无休止的循环中,所以我认为正在发生一些更根本的事情...我是说我在这里犯了某种小学生错误?
getBizImg()
永远不会返回URL,因为您只能在getStorageURLWithKey()
承诺的回调中返回它。
返回该承诺(并将方法类型更改为Promise<string>
并使用异步管道显示它:
getBizImg(): string {
console.log('GetBizImg');
if (this.business.Id) { // We have a Business Object
// return here
return this.userService.getStorageURLWithKey(this.business.ImageURL).then((url) => {
console.log(url);
return url;
}, reject => {
console.log('Rejected:' + reject);
});
} else {
return '';
}
}
<ion-content padding>
<ion-img [src]="getBizImg() | async"></ion-img>
</ion-content>
我认为您的异步getBizImg()是正确的。 你可以这样
ngOnInit() {
this.getBizImg().then((wibble) => {
console.log(wibble);
// just add here this.urlImage = wibble
});
}
在您的组件上添加一个urlImage。 并在html中
<ion-content padding>
<ion-img *ngIf="urlImage" [src]="urlImage" ></ion-img>
</ion-content>
或者如果您想从html调用它,我不确定,但是尝试asyncPipe https://angular.io/api/common/AsyncPipe
<ion-content padding>
<ion-img [src]="getBizImg() | async" ></ion-img>
</ion-content>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.