【发布时间】:2020-11-13 03:39:07
【问题描述】:
我对 Angular 和 Observables 有疑问,我在 Stackblizt 中重现了它:https://stackblitz.com/edit/angular-ivy-dl1y3y
说一下上下文:
- 我需要调用第一个网络服务。
- 使用第一次调用的数据,我需要调用第二个 Web 服务。
- 使用第二次调用的数据,我需要调用第三组 Web 服务(“父子关系”)
- 所有这些信息都将显示在一个表格中(使用Angular Datatables),我不想显示带有部分数据的表格(否则只要所有剩余的可观察项完成,剩余的数据就会弹出。另外我可能会面临一些其他问题,例如用户在部分数据尚不可用时单击按钮...)。所以:我希望所有的 observables 都完成,然后我将完整的对象传递给数据表,所有的东西都会立即显示出来!
- 我想用 Observables 来做,而不是 Promises
好的,我一步一步教你。
第 1 步
第一步是调用第一个 URL (assets/step-1-getAccountReference.json) 来检索帐户参考 ID:
{
"accountIdRef": "/assets/step-2.getAccount.json"
}
第 2 步
有了这个accountIdRef,我可以调用另一个URL("/assets/step-2.getAccount.json")来检索账户信息:
{
"accountId": "123",
"details": [
{
"nameRef": "/assets/step-3-pet-1-name.json",
"genderRef": "/assets/step-3-pet-1-gender.json"
},
{
"nameRef": "/assets/step-3-pet-2-name.json",
"genderRef": "/assets/step-3-pet-2-gender.json"
}
]
}
第 3 步
最后一步是通过调用其他一些 url(nameRef 和 genderRef)来检索 for each 宠物的所有详细信息。
如果您打开控制台,您应该会看到,如果我直接订阅并登录帐户,则会显示此信息(来自 step 1 和 step 2 的 Observables 已完成) :
{
"accountId": "123",
"details": [
{
"nameRef": "/assets/step-3-pet-1-name.json",
"genderRef": "/assets/step-3-pet-1-gender.json"
},
{
"nameRef": "/assets/step-3-pet-2-name.json",
"genderRef": "/assets/step-3-pet-2-gender.json"
}
]
}
如果我在 3 秒后再次登录该帐户,则会显示此信息(第 3 步中的所有 observables 都已完成):
{
"accountId": "123",
"details": [
{
"nameRef": "/assets/step-3-pet-1-name.json",
"genderRef": "/assets/step-3-pet-1-gender.json",
"name": "Santa's Little Helper",
"gender": "Male"
},
{
"nameRef": "/assets/step-3-pet-2-name.json",
"genderRef": "/assets/step-3-pet-2-gender.json",
"name": "Snowball II",
"gender": "Female"
}
]
}
我想等待所有 observables 完成(包括第 3 步),但当然是动态的,而不是使用固定的超时时间。
这是我现在所拥有的:
export class HttpService {
constructor(private http: HttpClient) {}
getAccount(): Observable<Account> {
return this.http.get("assets/step-1-getAccountReference.json").pipe( // Step 1
mergeMap((accountReference: AccountReference) => {
return this.http.get("" + accountReference.accountIdRef); // Step 2
}),
delay(500),
map((account: Account) => {
account.details.forEach((details: AccountDetails) => { // Step 3
let name$ = this.http.get("" + details.nameRef);
let gender$ = this.http.get("" + details.genderRef);
forkJoin([name$, gender$]).subscribe(results => {
details.name = results[0]["name"];
details.gender = results[1]["gender"];
});
});
return account;
})
);
}
}
那么,我该如何调整这段代码,使第 3 步是同步的?我应该使用哪个运算符来替换这个 forEach ?
感谢您的帮助!
【问题讨论】:
标签: angular rxjs observable