Angular 组合/简化在多个函数中调用的两个承诺
我开始习惯于承诺驱动的代码,但我发现自己极为频繁地重复一些代码。特别是,我有一个Ionic应用程序,我在其中进行许多API调用,在运行调用之前,我会检查是否存在Internet连接,以及用户是否经过身份验证。这些功能的结构如下所示: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 => {
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();
}