不知何故,使用cordova时http请求的catchError不起作用



所以昨天我在开发一些离线功能。因此,我添加了一个返回Observables的ApiService。目前,我为jwt-Authentication获取我的access_token,然后使用这个令牌为我的API-Request生成Header。请求成功后,我将结果保存到我的存储器中。这很好用。现在的问题是,我想检查一个不成功的请求(例如,服务器关闭,应用程序离线(,然后从存储中返回我存储的结果。但我无法让它发挥作用。

这是我的代码:

getJobs(): Observable<any> {
this.auth.checkToken()
return from(this.storage.get(ACCESS_TOKEN)).pipe(
switchMap(token => {
let options = this.auth.addToken(token)
return this.http.get(API_URL + "jobs", options)
}),
map(res => {
if (res) {
this.storage.set(JOBS, res)
return res
} else {
return from(this.storage.get(JOBS))
}
}),
catchError(() => {
return from(this.storage.get(JOBS))
})
)
}

进一步的调查表明,在服务器或应用程序离线后,map((和catchError((函数都没有执行。

更新:DJ House提供的解决方案是正确的。我的代码在我的浏览器中运行得很好,但如果我用ionic cordova build android构建我的应用程序,它会在this.http.get(...)之后卡住。所以很明显,cordova 有问题

解决方案:哇!神奇的事情发生了!我发现catchError方法在大约2分钟后被调用,这是一种减缓。。。所以我将实现一个超时。

谢谢亚麻

您可能面临的主要问题是您错误地使用了map。Map作用于一个正常值(通常,它不是可观察的(并返回一个新值。map()应始终返回相同类型的值。在您的map()中,您要么返回响应(我假设其类型为Jobs(,要么返回Observable<Jobs>。这将导致您的订阅者需要详细的逻辑来处理此问题。

看起来您正试图使用map()来设置本地存储,其中包含从您的api返回的作业。我建议使用tap(),因为您不会试图更改返回的值。

function getJobs(): Observable<any> {
this.auth.checkToken()
return from(this.storage.get(ACCESS_TOKEN)).pipe(
switchMap(token => {
let options = this.auth.addToken(token)
return this.http.get(API_URL + "jobs", options)
}),
// change to tap()
tap(res => {
if (res) {
this.storage.set(JOBS, res)
}
}),
catchError(() => {
return from(this.storage.get(JOBS))
})
)
}

如果switchMap抛出错误,则将跳过该抽头。这将确保您仅在从API收到值时设置存储。如果始终要设置存储(即使API抛出错误(,则将tap()移动到catchError()之后。

你能试着把catchError操作符作为管道方法中的第一个操作符吗。这是为了确保您在收到可观察到的错误后立即发现错误。请更改如下:

getJobs(): Observable<any> {
this.auth.checkToken()
return from(this.storage.get(ACCESS_TOKEN)).pipe(
switchMap(token => {
let options = this.auth.addToken(token)
return this.http.get(API_URL + "jobs", options)
}),
catchError(() => {
return from(this.storage.get(JOBS))
})
map(res => {
if (res) {
this.storage.set(JOBS, res)
return res
} else {
return from(this.storage.get(JOBS))
}
}),
)
}

最新更新