Angular ForkJoin中的计时器
我有一个带有3个GET调用的APIAngular ForkJoin中的计时器,angular,rxjs,rxjs6,Angular,Rxjs,Rxjs6,我有一个带有3个GET调用的API 获取环境 获得产品 获取特定环境中特定产品的状态 我试图做的是每5分钟轮询一次每个环境中每个产品的状态,以便在刷新的表中显示数据 获取环境和产品的调用应该执行一次,因为这是静态信息 let envs = this.http.get('http://my-api/envs); let products = this.http.get('http://my-api/products); forkJoin([envs, products]).subscribe(r
let envs = this.http.get('http://my-api/envs);
let products = this.http.get('http://my-api/products);
forkJoin([envs, products]).subscribe(results => {
//the code below should be executed every 5 mins and store the results in array
results[0].forEach(env => {
results[1].forEach(product => {
this.http.get('http://my-api/status/${env}/${product}')
})
})
})
任何帮助都将不胜感激。不确定这能实现什么,但它每五分钟在订阅中运行一次代码。更准确地说,它每5分钟调用一次
forkJoin
。如果执行forkJoin
所需的时间可变,则可能会使时间偏移一点。否则,您可以提前调用forkJoin并使用delay
和Date()上的一些数学运算将结果延迟到五分钟
const五分钟=1000*60*5;
计时器(0,5分钟)。管道(
开关映射(=>forkJoin({
envs:this.http.get('http://my-api/envs'),
产品:this.http.get('http://my-api/products')
}))
).subscribe({envs,products})=>{
环境forEach(环境=>{
products.forEach(产品=>{
//这个http调用没有任何作用?
this.http.get('http://my-api/status/${env}/${product}')
})
})
});
更新#1:最后呼叫的间隔。
这个调用您的This.http.get('http://my-api/status/${env}/${product}')
每5分钟调用一次,并将结果作为数组发送到订阅
由于明显的原因,没有对其进行测试。但它应该提供一个良好的起点
const五分钟=1000*60*5;
分叉连接({
envs:this.http.get('http://my-api/envs'),
产品:this.http.get('http://my-api/products')
}).烟斗(
地图({env,products})=>
envs.map(env=>
products.map(product=>
this.http.get('http://my-api/status/${env}/${product}')
)
).flat()
),
合并映射(statusCalls=>timer(0,5分钟)。管道(
合并映射(=>forkJoin(statusCalls))
))
).订阅(statusCallsResults=>{
//**使用结果更新视图**//
})
如果您确实希望按照之前的设置订阅,则可能如下所示:
const五分钟=1000*60*5;
分叉连接({
envs:this.http.get('http://my-api/envs'),
产品:this.http.get('http://my-api/products')
}).烟斗(
合并映射(res=>计时器(0,5分钟)。管道(
映射(=>res)
))
).subscribe({envs,products})=>{
//这是每五分钟一次
环境forEach(环境=>{
products.forEach(产品=>{
//这个http调用没有任何作用?
this.http.get('http://my-api/status/${env}/${product}')
})
})
});
更新#2:错误处理
forkJoin
将在其任何内部观察失败时失败。你可以用很多方法来处理这个问题。最基本的方法是将出错的流转换为发出null并成功完成的流。然后,forkJoin在每个数组位置都将有null
,并且有一个错误
可能是这样的:
const五分钟=1000*60*5;
分叉连接({
envs:this.http.get('http://my-api/envs'),
产品:this.http.get('http://my-api/products')
}).烟斗(
地图({env,products})=>
envs.map(env=>
products.map(product=>
this.http.get('http://my-api/status/${env}/${product}')管道(
catchError(err=>of(null))
)
)
).flat()
),
合并映射(statusCalls=>timer(0,5分钟)。管道(
合并映射(=>forkJoin(statusCalls))
))
).订阅(statusCallsResults=>{
//**使用结果更新视图**//
})
错误代码500不是很具有描述性。当请求失败时,您可以查看重试操作符以重试请求。可与catchError
组合使用
不从服务器获取该错误首先取决于您。您可以将forkJoin
包装在setInterval(()=>{},300000)中代码>保存对变量的setInterval调用,以便在需要时取消它。(否则,如果前一次通话尚未结束,通话可能会堆积起来,但5分钟后可能永远不会发生…)谢谢。正如您提到的,这段代码每5分钟调用一次forkJoin
,但我不希望这样。我只想调查一下情况,就这样。因为环境和产品是一种静态信息,但是状态可能会随着时间的推移而改变,所以我们进行了一次更新,每5分钟只进行一次状态呼叫。这非常有帮助,谢谢!有一件事,我在flat()中得到了一个错误,你是说flatMap吗?只是将结果数组展平,因为它是嵌套的。您可以在此处检查兼容性,如果愿意,可以使用另一种方法:举个例子,这里有一个stackblitz和Observable: