每隔一段时间获取一次请求,并进行错误处理
GET Request every interval time, with errors handling
我觉得问题很简单,但是我无法自行修复这段代码
我有一项服务正在执行一些 GET 请求。 GET 通常 returns 200,但有时返回 410。
我想每隔一段时间发出请求,例如每秒。
问题是当我为此使用可观察的机制时,它首先失败“410”,然后它在控制台上无限返回 410。
我的服务代码:
getStatistic(){
var headers = new Headers();
headers.append("Content-Type", "application/x-www-form-urlencoded");
var options = new RequestOptions({headers: headers});
return this.http.get('http://localhost:8080/resource',options)
.retryWhen(errors => errors.delay(5000))
.map(
(response:Response) => {
return response.json();
}
)
}
handleError(error:any){
if(error.status === 404){
return Observable.of(false)
}else if(error.status===410){
return Observable.throw({code:error.status, msg:error._body})
}else{
return Observable.of(false)
}
}
和 Observable:
var observable = TimerObservable.create(5000, 1000)
.takeWhile(() => true)
.subscribe(() => {
this.statisticService.getStatistic()
.subscribe(
(data) => {
console.log("data",data)
},
(err) => {
console.log("err",err)
}
);
},error2 => console.log("error"));
回复是这样的:
200
200
200
200
410 <- 目前所有响应都不是来自对服务器的请求,只是缓存
410
410
...
首先,你需要改变你思考问题的方式,开始更加功能化和被动地思考。
这说起来容易做起来难,但通过实践,这将成为第二天性,并可能使您的许多代码更容易理解。
让我们逐一解决每个问题。
减少数组和对象等新形成的数据结构的数量。而是将一个函数的输出作为另一个函数的输入。
目前您正在为每个 api 调用订阅一个可观察对象。要链接所有 api 调用并并行调用它们,我们可以使用 "forkJoin"。请注意,有很多像 "forkJoin" 这样的运算符,要了解所有这些运算符是很费力的。我需要 google "rxjs observables parallel" 才能知道 "forkJoin" 是我们需要的。
如果我们需要将来自observable的数据结构转换为另一个数据结构,我们需要使用"map"运算符
如果我们需要来自 observable 的数据来满足某个谓词,我们需要使用 "filter" 运算符
如果我们需要在调用另一个 observable 之前从一个 observable 获得响应,我们将使用运算符 "flatMap"
您总是可以 console.log 在任何运算符中了解到达的数据
例如:forkJoin(...obsSources).map(x=> {
console.log(x)
})
- 如果您遇到困难并且找不到解决您问题的运算符,您可以订阅可观察对象并使用订阅函数调用其他函数,该函数从订阅函数发出的内容中获取其参数(而不是创建一个新数组或对象)
例如:
forkJoin(...obsSources).subcribe(x=> {
func1(x)
})
我在没有测试代码的情况下解决了这个问题,所以它可能不适用于您的特殊情况,但我想分享一下 rxjs observables 的实际工作原理。
import { forkJoin } from "rxjs/observable/forkJoin";
const obsSources = distinctDataAssIDs
.map(dataASSID=>this.api.getDataAssociationByID(dataASSID))
forkJoin(...obsSources)
.map(arrResults => arrResults.map(arrResult=>
arrResult.body.entities.DATAASSOCIATIONS[0]))
.filter(dataAss => dataAss.DATAOBJECTS !== undefined)
.map(dataAss => Array.from(new Set(dataAss.DATAOBJECTS)))
.flatMap(secondMethodResult => this.service.thirdMethod(secondMethodResult))
难道是因为
A 410 response is cacheable by default.
客户端缓存该响应,甚至不再尝试调用服务器。
我觉得问题很简单,但是我无法自行修复这段代码
我有一项服务正在执行一些 GET 请求。 GET 通常 returns 200,但有时返回 410。
我想每隔一段时间发出请求,例如每秒。 问题是当我为此使用可观察的机制时,它首先失败“410”,然后它在控制台上无限返回 410。
我的服务代码:
getStatistic(){
var headers = new Headers();
headers.append("Content-Type", "application/x-www-form-urlencoded");
var options = new RequestOptions({headers: headers});
return this.http.get('http://localhost:8080/resource',options)
.retryWhen(errors => errors.delay(5000))
.map(
(response:Response) => {
return response.json();
}
)
}
handleError(error:any){
if(error.status === 404){
return Observable.of(false)
}else if(error.status===410){
return Observable.throw({code:error.status, msg:error._body})
}else{
return Observable.of(false)
}
}
和 Observable:
var observable = TimerObservable.create(5000, 1000)
.takeWhile(() => true)
.subscribe(() => {
this.statisticService.getStatistic()
.subscribe(
(data) => {
console.log("data",data)
},
(err) => {
console.log("err",err)
}
);
},error2 => console.log("error"));
回复是这样的: 200 200 200 200 410 <- 目前所有响应都不是来自对服务器的请求,只是缓存 410 410 ...
首先,你需要改变你思考问题的方式,开始更加功能化和被动地思考。 这说起来容易做起来难,但通过实践,这将成为第二天性,并可能使您的许多代码更容易理解。
让我们逐一解决每个问题。
减少数组和对象等新形成的数据结构的数量。而是将一个函数的输出作为另一个函数的输入。
目前您正在为每个 api 调用订阅一个可观察对象。要链接所有 api 调用并并行调用它们,我们可以使用 "forkJoin"。请注意,有很多像 "forkJoin" 这样的运算符,要了解所有这些运算符是很费力的。我需要 google "rxjs observables parallel" 才能知道 "forkJoin" 是我们需要的。
如果我们需要将来自observable的数据结构转换为另一个数据结构,我们需要使用"map"运算符
如果我们需要来自 observable 的数据来满足某个谓词,我们需要使用 "filter" 运算符
如果我们需要在调用另一个 observable 之前从一个 observable 获得响应,我们将使用运算符 "flatMap"
您总是可以 console.log 在任何运算符中了解到达的数据 例如:
forkJoin(...obsSources).map(x=> { console.log(x) })
- 如果您遇到困难并且找不到解决您问题的运算符,您可以订阅可观察对象并使用订阅函数调用其他函数,该函数从订阅函数发出的内容中获取其参数(而不是创建一个新数组或对象)
例如:
forkJoin(...obsSources).subcribe(x=> { func1(x) })
我在没有测试代码的情况下解决了这个问题,所以它可能不适用于您的特殊情况,但我想分享一下 rxjs observables 的实际工作原理。
import { forkJoin } from "rxjs/observable/forkJoin";
const obsSources = distinctDataAssIDs
.map(dataASSID=>this.api.getDataAssociationByID(dataASSID))
forkJoin(...obsSources)
.map(arrResults => arrResults.map(arrResult=>
arrResult.body.entities.DATAASSOCIATIONS[0]))
.filter(dataAss => dataAss.DATAOBJECTS !== undefined)
.map(dataAss => Array.from(new Set(dataAss.DATAOBJECTS)))
.flatMap(secondMethodResult => this.service.thirdMethod(secondMethodResult))
难道是因为
A 410 response is cacheable by default.
客户端缓存该响应,甚至不再尝试调用服务器。