繁体   English   中英

异步函数返回promise,但是调用函数无法解析

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM