Angular 组合/简化在多个函数中调用的两个承诺

Angular 组合/简化在多个函数中调用的两个承诺,angular,typescript,ionic-framework,promise,ionic3,Angular,Typescript,Ionic Framework,Promise,Ionic3,我开始习惯于承诺驱动的代码,但我发现自己极为频繁地重复一些代码。特别是,我有一个Ionic应用程序,我在其中进行许多API调用,在运行调用之前,我会检查是否存在Internet连接,以及用户是否经过身份验证。这些功能的结构如下所示: noteCreate(): Promise<any> { return new Promise (resolve => { this.connCheck() .then(success => {

我开始习惯于承诺驱动的代码,但我发现自己极为频繁地重复一些代码。特别是,我有一个Ionic应用程序,我在其中进行许多API调用,在运行调用之前,我会检查是否存在Internet连接,以及用户是否经过身份验证。这些功能的结构如下所示:

  noteCreate(): Promise<any> {
    return new Promise (resolve => {
      this.connCheck()
      .then(success => {
        if (success) {
          this.authCheck('Please login first!')
          .then(success => {
            if (success) {

              // API CALL

            }
          });
        }
      })
    });
  }

承诺的全部意义在于能够链接逻辑。如果链条的任何一部分出现故障,您可以在末端抓住它。你可以简单地做:

return this.connCheck()
  .then(() => this.authCheck())
  .then(() => {
     ... API call...
  })
  .catch(error => ...)
如果任何承诺被拒绝,将触发捕获


你可能应该把捕获物放在承诺链的最末端

此代码包含反模式,有时称为反模式和承诺构造反模式(的近亲)

已经有一个承诺可以被锁住。没有必要再创建一个,
newpromise(resolve=>…)

承诺需要有限的嵌套水平。所有的承诺都应该受到约束。如果一个承诺只是挂在嘴边,没有得到回报,这就是一个错误

如果存在多个条件,可以通过拒绝打破承诺链,将其展平:

  noteCreate(): Promise<any> {
    const alreadyAuthorized = new Error();

    return this.connCheck()
    .then(success => {
      if (success)
        return this.authCheck('Please login first!')
      else
        throw alreadyAuthorized ;
    })
    .then(success => {
       if (success) {
         return ... // API CALL
       }
    ))
    .catch(err => {
      if (err === alreadyAuthorized)
        return;
      else
        throw err;
    });
  }
this.http.get(…).subscribe(…)
与Promissions结合使用是错误的。可观测数据可轻松转换为承诺并返回:

  connCheck(): Promise<boolean> {
    return this.http.get(this.myURL() + '/heartbeat/', {responseType: 'text'})
    .map(Boolean) // maps data to a boolean
    .toPromise();
  }
connCheck():承诺{
返回this.http.get(this.myURL()+'/heartbeat/',{responseType:'text'})
.map(布尔)//将数据映射到布尔值
.toPromise();
}

不幸的是,这与原始代码不同。如果
this.authCheck()
未能通过检查,则会产生解析值,而不是。在拒绝中肯定是一个有用的响应,但@estus提出了正确的观点。它不会像我需要的那样工作。很高兴它起了作用。
  async noteCreate(): Promise<any> {
    if (!(await this.connCheck()))
      return;

    if (!(await this.authCheck('Please login first!')))
      return;

    return ... // API CALL        
  }
  connCheck(): Promise<boolean> {
    return this.http.get(this.myURL() + '/heartbeat/', {responseType: 'text'})
    .map(Boolean) // maps data to a boolean
    .toPromise();
  }