订阅在promise Angular 6中放置的http.post

Jer*_*rry 3 javascript observable rxjs firebase-authentication angular

当我将promise与subscribe和另一个异步任务混合在一起时,这对我来说变得很复杂。

这是我的身份验证服务:

getCurrentUserToken(){
    return new Promise((resolve,reject)=>{
      firebase.auth().currentUser.getIdToken(/* forceRefresh */ true).then(function(idToken) {
        resolve(idToken)
      }).catch(function(error) {
        reject(error)
      });
    }) 
  }
Run Code Online (Sandbox Code Playgroud)

这是我的http服务:

sendEmail(email) {

    return this.authService.getCurrentUserToken().then(token => {
      const httpOptions = {
        headers: new HttpHeaders({
          'Content-Type': 'application/json',
          'Authorization': 'Basic server-Password',
        })
      };
      let data = email
      data['idToken'] = token
      return this.http.post(this.apiServer + 'sendEmail', data, httpOptions)
    })

  }
Run Code Online (Sandbox Code Playgroud)

这就是我sendEmail(email)在组件上调用函数的方式:

    Observable.fromPromise(this.httpService.sendEmail(element)).subscribe(
      data3 => {
        console.log(data3)

      }, error => {
        console.log(error)
      }
    ))
Run Code Online (Sandbox Code Playgroud)

我必须将currentUserToken传递给API,以使API验证用户会话,但两者均getCurrentUserToken() sendEmail()以异步方式运行,因此我必须使用Promise传递Tokento sendEmail()函数,并让sendEmail函数调用API来发送API电子邮件。

没有承诺,我可以这样订阅http.post

this.httpService.sendEmail(element).subscribe(
          data3 => {
            console.log(data3)

          }, error => {
            console.log(error)
          }
        ))
Run Code Online (Sandbox Code Playgroud)

不幸的是,当我向其中添加promise时,我搞砸了,console.log返回了以下内容: Observable {_isScalar: false, source: Observable, operator: MapOperator}

请告知如何在中订阅http.post该位置Promise

Sid*_*era 5

完全没有必要在这里复杂化事情。

我将在此处使用async/ await语法,为此,我们必须使用Promises而不是Observables。好的事情是,我们可以利用值toPromise()上的方法将Observable其更改为Promise

还要关注我在代码中的注释

这是实现

对于 getCurrentUserToken

getCurrentUserToken() {
  return firebase.auth().currentUser.getIdToken(true);
  // This will already return a Promise<string>
  // So no need to do a .then and then return from there.
}
Run Code Online (Sandbox Code Playgroud)

对于 sendEmail

async sendEmail(email) {
  // Since getCurrentUserToken returns a Promise<string> we can await it
  const token = await this.authService.getCurrentUserToken();
  // token will now have the Current User Token
  const httpOptions = {
    headers: new HttpHeaders({
      'Content-Type': 'application/json',
      'Authorization': 'Basic server-Password',
    })
  };
  let data = email
  data['idToken'] = token
  return this.http.post(this.apiServer + 'sendEmail', data, httpOptions).toPromise();
  // Notice how we're calling the .toPromise() method here 
  // to change Observable into a Promise
}
Run Code Online (Sandbox Code Playgroud)

如何使用它?

该代码将放在您以前调用的Component Method中this.httpService.sendEmail请务必将功能标记为async透彻。

// We can only await something in a function which is declared of type async
async sendEmail() {
  try {
    const data = await this.httpService.sendEmail(element);
    // Since sendEmail again returns a Promise, I can await it.
    console.log(data);
  } catch (error) {
    console.log(error);
  }
}
Run Code Online (Sandbox Code Playgroud)