使用rxjs Angular和ngrx同步处理Observable以防止太多HTTP请求超时
我有以下代码。它获取一个患者数组并构建一个rows对象使用rxjs Angular和ngrx同步处理Observable以防止太多HTTP请求超时,angular,rxjs,observable,rxjs5,ngrx,Angular,Rxjs,Observable,Rxjs5,Ngrx,我有以下代码。它获取一个患者数组并构建一个rows对象this.rows,我在angular 4组件前端的一个表中显示(我也在使用rxjs 5.5) 我的问题是每行的hasAlert属性都是通过调用hasAlerts()来分配的。在HasAlerts方法中,我通过this.dataService.fetchItems()为每个患者发出http请求 当有许多患者时,太多的HTTP请求将异步发生,并且它们将从HasAlerts()开始失败(超时)。是否有方法限制这一点,或者从HasAlerts()一
this.rows
,我在angular 4组件前端的一个表中显示(我也在使用rxjs 5.5)
我的问题是每行的hasAlert属性都是通过调用hasAlerts()来分配的。在HasAlerts方法中,我通过this.dataService.fetchItems(
)为每个患者发出http请求
当有许多患者时,太多的HTTP请求将异步发生,并且它们将从HasAlerts()开始失败(超时)。是否有方法限制这一点,或者从HasAlerts()一次处理一个可观察到的请求?
下面是解决这个问题的可能方法
ngOnInit(): void {
this.store.dispatch(new patients.Load([]));
this.patients$ = this.store.select(fromPatients.getAll);
var patientsAlertsProcessed =0;
this.patients$.debounceTime(2000).map(p =>{//Emits Observable<Patient[]>s, the debounceTime is to take the last one as it builds up
this.rows = p.map(pat => {// p = Patient[], iterate through the array of patients
var observations=0;
var rowX= {
username: pat.username,
id: pat.id,
hasAlert:false,
};
if (patientsAlertsProcessed<15){// this is done to throttle the HasAlerts Method
this.hasAlerts(pat).do(x => {
observations++;
if (observations>0)
{
rowX.hasAlert=true;
}
}).subscribe();
patientsAlertsProcessed++;
}
return rowX;
});
}).subscribe(
()=> { },
()=> {
this.table.recalculatePages();
}
);
}
hasAlerts(pat: Patient): Observable<Observation> {
var obs$= this.dataService.fetchItems<Observation>(// this is making an HTTP get request
"Observation",
null,
pat.id
).filter(function (x){
if (x.category.coding[0].code == "GlucoseEvent"){
return true;
}
else{
return false;
}
}
);
return obs$;
}
ngOnInit():void{
this.store.dispatch(新患者.Load([]);
this.patients$=this.store.select(fromPatients.getAll);
var patientsAlertsProcessed=0;
this.patients$.debounceTime(2000).map(p=>{//)发出可见光,debounceTime将在其建立时取最后一个
this.rows=p.map(pat=>{//p=Patient[],遍历患者数组
var观测值=0;
变量rowX={
用户名:pat.username,
id:pat.id,
hasAlert:错,
};
如果(患者)已处理{
观察++;
如果(观测值>0)
{
rowX.hasAlert=true;
}
}).subscribe();
patientsAlertsProcessed++;
}
返回rowX;
});
}).订阅(
()=> { },
()=> {
this.table.recomparePages();
}
);
}
hasAlerts(pat:患者):可观察到{
var obs$=this.dataService.fetchItems(//这是在发出HTTP get请求
“观察”,
无效的
身份证
).过滤器(功能(x){
如果(x.category.coding[0].code==“GlucoseEvent”){
返回true;
}
否则{
返回false;
}
}
);
返回obs$;
}
您可能想尝试一下这些方法
const concurrency = 10;
const rowsWithAlerts = [];
this.patients$.debounceTime(2000)
.switchMap(patients => Observable.from(patients)) // patients is of type Patient[]
.mergeMap(patient => {
rowsWithAlerts.push(patient);
this.hasAlerts(patient).do(
hasAlertsResult => {
// here you have hold to both the patient and the result of
// hasAlerts call
patient.hasAlerts = hasAlertsResult;
}}), concurrency)
.subscribe(
() => this.rows = rowsWithAlerts;
)
这里的关键是使用mergeMap
操作符,将并发级别设置为一个值,在本例中为10,但显然可以是任何值
这允许限制您同时订阅的可观察对象的数量,在您的情况下,这意味着限制您进行的http调用的数量。尝试一下,我注意到您对rxjs很精通。当您熟悉rxjs时,有没有什么资源对您有帮助?我设置此的逻辑。我会在在ListCMAP行中的“=”之后,我不建议这样做。你必须考虑,<>代码>患者< /COD>数组,你得到的参数是SwitcMax,是一个与你的代码不同的数组。在您的示例中,要将用户名ID和警报作为属性分配给rowX?也可以在开关映射行中进行观察。从(p)p未定义您是对的,它不应该是p,而应该是
switchMap
中的患者。我还更新了我的答案,以便您为每个患者设置hasAlerts
标志,并将每个患者推入行数组。