在 foreach 中等待几个可观察的 rxjs 直到完成执行另一个
Posted
技术标签:
【中文标题】在 foreach 中等待几个可观察的 rxjs 直到完成执行另一个【英文标题】:Wait for several rxjs observable inside foreach till finished to execute an another 【发布时间】:2020-02-25 20:57:15 【问题描述】: 我想循环检查 checked_checkboxes 值。 foreach 我想做一个 POST 请求。 然后,当 foreach 中的所有 POST 请求完成后,我想获取刚刚查询的数据。问题:
我的 get 函数与我的 post 函数是分开的,所以 post 查询没有完成,它会执行 get,所以它的结果是一个空的 get,因为帖子还没有发布。解决方案:
将 observables 添加到数组中,然后将它们放入 foreach 末尾的 forkJoin 中。
我所看到的可能:
将 observable 转化为 promise 然后使用 async await,不太适应这个 可以使用 forkJoin 操作符来执行一些 observables 并等待它们全部完成。我的 API 服务返回 RxJs observables,我在 Angular 8 中,这是两个函数: 首先是 AddVacation() 将发布一些数据,然后 getAgentsInSfihtDispo() 将获取发布的数据。
addVacation()
let counter = 0;
const shift_id = this.selectedShiftForMaincouranteModify;
const shift_date = this.modifyForm.value.dateDeb.format('YYYY-MM-DD');
this.api.sendGetRequest("/api/shift_dates/" + shift_date, true, null, null)
.subscribe((data) =>
this.agents_dispo_checked.forEach((agent) =>
const agent_id = agent.id;
if (data)
this.api.sendPostRequest('/api/shift_dos', true, null,
shift_id: shift_id, shift_date: shift_date, agent_id: agent_id )
.subscribe();
else
this.api.sendPostRequest("/api/shift_dates", true, null, date: shift_date )
.subscribe((data3) =>
if (data3.error === "L'association existe deja dans la base de données")
this.api.sendPostRequest('/api/shift_dos', true, null,
shift_id: shift_id, shift_date: shift_date, agent_id: agent_id )
.subscribe();
else
this.api.sendPostRequest('/api/shift_dos', true, null,
shift_id: shift_id, shift_date: data3.date, agent_id: agent_id )
.subscribe();
);
counter++;
);
if (this.agents_dispo_checked.length === counter)
this.isOpenSaisieVacation = false;
this.getAgentsInShiftAndDispo();
,
(err) => console.error(err));
getAgentsInShiftAndDispo()
this.agentsInShift = [];
this.agents_dispo = [];
this.agentsInShiftSelectedFormArray.clear();
this.agentsDispoFormArray.clear();
if (this.selectedShiftForMaincouranteModify !== 0 &&
(this.modifyForm.controls.dateDeb.value !== "" || this.modifyForm.controls.dateDeb.value !== null || this.modifyForm.controls.dateDeb.value !== undefined))
const shift_id = this.selectedShiftForMaincouranteModify;
const goodFormatDate = this.modifyForm.value.dateDeb.format('YYYY-MM-DD');
this.api.sendGetRequest('/api/shift_dos/byShiftAndDate/' + shift_id + "/" + goodFormatDate, true, null, null)
.subscribe((data) =>
if (data)
data.forEach((item) =>
this.agentsInShift.push(item.agent);
);
, (err) => console.error(err),
() =>
this.agentsInShift.map((o, i) =>
const control = new FormControl(true); // if first item set to true, else false
this.agentsInShiftSelectedFormArray.push(control);
);
const difference = this.agentsMaintenance.filter((obj) =>
return !this.agentsInShift.some((obj2) =>
return obj.id === obj2.id;
);
);
this.agents_dispo = difference;
this.agents_dispo.map((o, i) =>
const control = new FormControl(false); // if first item set to true, else false
this.agentsDispoFormArray.push(control);
);
);
在此先感谢您带领我进入 RxJs 运营商的广阔世界。
【问题讨论】:
您的“我所看到的可能”是对的。我理解您对 async-await 的疑虑。但我希望您不要认为每次迭代都需要这样做。只需执行 Promise.all()。你对 forkJoin 有什么问题? 嗯,有些人对我说 observable 是处理 http 请求的更好方法,所以我更喜欢使用它们而不是 promise。 【参考方案1】:您必须将所有 Observables 推入一个数组,并使用 forkJoin。
private observables = [];
addVacation()
let counter = 0;
const shift_id = this.selectedShiftForMaincouranteModify;
const shift_date = this.modifyForm.value.dateDeb.format('YYYY-MM-DD');
this.api.sendGetRequest("/api/shift_dates/" + shift_date, true, null, null)
.subscribe((data) =>
this.agents_dispo_checked.forEach((agent) =>
const agent_id = agent.id;
if (data)
this.observables.push(this.api.sendPostRequest('/api/shift_dos', true, null,
shift_id: shift_id, shift_date: shift_date, agent_id: agent_id ));
else
this.observables.push(this.api.sendPostRequest("/api/shift_dates", true, null, date: shift_date )
.subscribe((data3) =>
if (data3.error === "L'association existe deja dans la base de données")
this.observables.push(this.api.sendPostRequest('/api/shift_dos', true, null,
shift_id: shift_id, shift_date: shift_date, agent_id: agent_id ));
else
this.observables.push(this.api.sendPostRequest('/api/shift_dos', true, null,
shift_id: shift_id, shift_date: data3.date, agent_id: agent_id ));
);
counter++;
);
if (this.agents_dispo_checked.length === counter)
this.isOpenSaisieVacation = false;
forkJoin(this.observables)
.subscribe(val => this.getAgentsInShiftAndDispo());
,
(err) => console.error(err));
getAgentsInShiftAndDispo()
this.agentsInShift = [];
this.agents_dispo = [];
this.agentsInShiftSelectedFormArray.clear();
this.agentsDispoFormArray.clear();
if (this.selectedShiftForMaincouranteModify !== 0 &&
(this.modifyForm.controls.dateDeb.value !== "" || this.modifyForm.controls.dateDeb.value !== null || this.modifyForm.controls.dateDeb.value !== undefined))
const shift_id = this.selectedShiftForMaincouranteModify;
const goodFormatDate = this.modifyForm.value.dateDeb.format('YYYY-MM-DD');
this.api.sendGetRequest('/api/shift_dos/byShiftAndDate/' + shift_id + "/" + goodFormatDate, true, null, null)
.subscribe((data) =>
if (data)
data.forEach((item) =>
this.agentsInShift.push(item.agent);
);
, (err) => console.error(err),
() =>
this.agentsInShift.map((o, i) =>
const control = new FormControl(true); // if first item set to true, else false
this.agentsInShiftSelectedFormArray.push(control);
);
const difference = this.agentsMaintenance.filter((obj) =>
return !this.agentsInShift.some((obj2) =>
return obj.id === obj2.id;
);
);
this.agents_dispo = difference;
this.agents_dispo.map((o, i) =>
const control = new FormControl(false); // if first item set to true, else false
this.agentsDispoFormArray.push(control);
);
);
【讨论】:
谢谢你,我正在寻找:D 很高兴为您提供帮助!如果它按预期工作,请不要忘记请接受答案。这也将帮助其他用户。谢谢!以上是关于在 foreach 中等待几个可观察的 rxjs 直到完成执行另一个的主要内容,如果未能解决你的问题,请参考以下文章
在 Angular 6 中使用 rxjs 可观察对象的目的是啥?与 async/await 相比,rxjs 的优势是啥? [复制]