2017-02-12 86 views
0

我开始使用async await模式更超过标准无极语法,因为它可以使代码更平坦。我已经和他们一起玩过并尝试过,并且想法我明白如何使用它们。打字稿异步伺机并不似乎总是等待(“块回来”)

那现在降临摇摇欲坠下来!

我有一个返回无极功能...

private async checkSecurityTokenForNearExpiry(): Promise<boolean> { 
     const expiryOffset = 10; 
     try {  
      let existingToken = await this.userAuthorisationService.getSecurityToken(); 
      if (existingToken != null && !existingToken.isTokenExpired(expiryOffset)) { 
      return true; 
      } 

      // Attempt to get a new token. 
      this.logger.debug('checkSecurityTokenForNearExpiry requesting new token.'); 
      this.getSecurityTokenWithRefreshToken().subscribe(obs => { 
      return true; 
      }, 
      error => { 
      // All errors already logged 
      return false; 
      }); 
     } catch (error) { 
      this.logger.error(`checkSecurityToken ${error}`); 
      return false; 
     } 
     } 

这正好调用返回一个承诺,也有可观察到的其他功能,然而这一切似乎是确定。

然后我调用该函数如下...

this.getDataStoreValues().then(async() => { 

     await this.checkSecurityTokenForNearExpiry(); // <-- not waiting 

     requestData(); // <-- this is called before checkSecurityTokenForNearExpiry returns 
     ... 

这里面另一个无极then回调标记为async,(应该是吧!),但我报警调用this.checkSecurityTokenForNearExpiry()不在我看到requestData()被调用之前完成。我不需要booleancheckSecurityTokenForNearExpiry的结果,但添加这个只是为了看看返回的东西是否会有所不同,但它不会。

在这里,我输了!

有谁知道我在这里失踪?

在此先感谢!

回答

1

async/await是否按预期工作,但有两个因素是防止你的代码无法正常工作。

  1. 可观察物体与async功能没有特别的相互作用。这意味着它们正在火中,而且正如它们在正常功能中一样。你是不是在等待getSecurityTokenWithRefreshToken但即使你没有await它,它仍然不会,只要你想,因为结果实际上是由包裹在一个Promise调用subscribe返回的订阅行为。

  2. 作为subscribe的参数采用的回调无意返回值,因此Observable实现不会传播其结果。

为了使这项工作,你需要将Observable转换为Promise如下

async checkSecurityTokenForNearExpiry(): Promise<boolean> { 
    const expiryOffset = 10; 
    try { 
     let existingToken = await this.userAuthorisationService().getSecurityToken(); 
     if (existingToken != null && !existingToken.isTokenExpired(expiryOffset)) { 
      return true; 
     } 
     // Attempt to get a new token. 
     this.logger.debug('checkSecurityTokenForNearExpiry requesting new token.'); 
     try { 
      await this.getSecurityTokenWithRefreshToken().toPromise(); 
      return true; 
     } catch (error) { 
      return false; 
     } 
    } catch (error) { 
     this.logger.error(`checkSecurityToken ${error}`); 
     return false; 
    } 
} 

请注意,如果您使用的RxJS您可能需要添加以下进口

import 'rxjs/add/operator/toPromise'; 
+1

感谢您的深入解释!所以这就是Observable问题。 'toPromise()'修复了它,并且节省了我不得不将它包装在一个Promise中,并手动地'解析'(并且我需要确保我在'getSecurityTokenWithRefreshToken()'中的observable上调用'complete()',否则它会不回来,我也错过了)。另外一个需要注意的地方。 – peterc

+0

关于'complete'的有趣评论,我也没有考虑过 –