javascript - 订阅放置在 Promise Angular 6 中的 http.post
问题描述
当我将 promise 与 subscribe 和另一个异步任务混合在一起时,这对我来说变得很复杂。
这是我的身份验证服务:
getCurrentUserToken(){
return new Promise((resolve,reject)=>{
firebase.auth().currentUser.getIdToken(/* forceRefresh */ true).then(function(idToken) {
resolve(idToken)
}).catch(function(error) {
reject(error)
});
})
}
这是我的 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)
})
}
这就是我sendEmail(email)
在组件中调用函数的方式:
Observable.fromPromise(this.httpService.sendEmail(element)).subscribe(
data3 => {
console.log(data3)
}, error => {
console.log(error)
}
))
我必须将 currentUserToken 传递给 API 以让 API 对用户会话进行身份验证。尽管如此,两者getCurrentUserToken()
sendEmail()
都在异步运行,所以我必须使用Promise
传递Token
tosendEmail()
函数,并让 sendEmail 函数调用 API 发送电子邮件。
没有承诺,我可以http.post
像这样订阅:
this.httpService.sendEmail(element).subscribe(
data3 => {
console.log(data3)
}, error => {
console.log(error)
}
))
不幸的是,当我将承诺添加到其中时,我搞砸了,console.log 正在返回:
Observable {_isScalar: false, source: Observable, operator: MapOperator}
请告知如何订阅http.post
放在Promise
.
解决方案
这里真的没有必要让事情复杂化。
我将在这里使用async
/await
语法,为此,我们必须使用Promise
s 而不是Observable
s。好消息是,我们可以利用值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.
}
为了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
}
如何使用它?
此代码将进入您之前调用的组件方法中this.httpService.sendEmail
。请务必将该功能标记async
为 THOUGH。
// 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);
}
}
推荐阅读
- mysql - 通过命令 UPDATE 将文本和数据插入一列
- angularjs - 角度表中的过滤仅适用于当前页面
- c++ - 未存储命令行参数(使用 boost)
- excel - 如果我指定小时数和天数,则将小时数复制到天数中
- web - 如何在兼容 QWC 的 Web 服务中实现客户端身份验证(2 路 SSL)?
- sql - WHERE 子句块数据表分页中的 PDO 绑定参数 (?)
- mysql - 为特定值选择每个最新行
- python - 日期范围内的 DataFrame 选择返回无行
- amazon-web-services - 如果连接到其他 CDN 提供商,如何在 AWS S3 上为我的文件创建会话令牌?
- python - pycharm 是如何工作的?他们是如何与口译员挂钩的?