Angular 订阅以等待响应
Angular make subscribe to wait for response
我正在尝试订阅 Observable 并从响应中分配一些数据,但不知何故我的代码没有等待响应。基本上 console.log(this.newIds) 首先运行并且始终为空,因为订阅不等待来自后端的响应。我如何强制我的代码等待响应的到来?
this.repository.getById(Ids).subscribe((response) => {
console.log(response);
this.newIds = response.map((id) => {
return id;
});
});
console.log(this.newIds);
如果您将代码放在订阅回调中。它将在您收到 back-end 的响应后执行。您在该函数之外编写的所有代码都将直接执行。
this.repository.getById(Ids).subscribe((response) => {
//Code will execute when back-end will respond
console.log(response);
this.newIds = response.map((id) => {
return id;
});
console.log(this.newIds);
});
//Code will execute immediately
另请参阅:https://angular.io/guide/observables#creating-observables
这是正常行为,因为您的 console.log(this.newIds);
在订阅之外,您只需要将它移到 .subscribe() 方法中:
this.repository.getById(Ids).subscribe((response) => {
console.log(response);
this.newIds = response.map((id) => {
return id;
});
console.log(this.newIds);
});
如果你想在订阅之外使用 this.newIds 并在观察者的结果之后立即使用,你可以使用 RxJs .toPromise() 将其用作承诺并将方法更改为异步:
async callerFn(){
const response = await this.repository.getById(Ids).toPromise();
this.newIds = response.map((id) => {
return id;
});
console.log(this.newIds);
// use your property here
}
是的,因为 Javascript 正在解释 line-by-line 执行,因此它不会等待其他进程完成。这就是为什么最后一个控制台将 return 未定义的原因。同时,如果您使用订阅者内部的控制台,那么您将获得正确的日志,因为订阅者将等待响应并将其与 this.newIds
绑定
this.repository.getById(Ids).subscribe((response) => {
console.log(response);
this.newIds = response.map((id) => {
return id;
});
console.log(this.newIds);
});
在这里,我附上了一篇关于可观察订阅的好读物
https://betterprogramming.pub/observables-vs-promises-which-one-should-you-use-c19aef53c680
除此之外,如果您想在订户范围之外使用 newIds 访问权限,请将 promise 与 async await 结合使用。这里我添加了一个示例
async getAsyncData() {
this.asyncResult = await this.httpClient.get<Employee>(this.url).toPromise();
console.log('No issues, I will wait until promise is resolved..');
}
我会以不同的方式处理:如果您必须重新映射值,您可以使用 map
运算符:
this.repository.getById(Ids)
.pipe(map(response) => response.map(id => id))
.subscribe((id) => {
console.log(response);
this.newIds = id;
});
实际上,我不明白为什么你需要映射一个你已经拥有的值,但我认为这是明确的解决方案。
你可以这样做..
您的组件文件如下所示
newIds: Observable<any> = of(this.id).pipe(
concatMap((id) =>
this.getId(id).pipe(map((data) => data.map((rowId) => rowId.id)))
)
);
getId(id: any) {
return of([{ id: 1 }, { id: 2 }, { id: 3 }]);
}
您的 html 文件如下所示,并使用异步管道进行订阅。在这里你可以使用 concateMap 管道 rxjs 运算符顺序调用 observable,然后将值赋给你的 newId 变量。
<pre>
{{ newIds | async }}
</pre>
现场演示linkStackblitz Link
我正在尝试订阅 Observable 并从响应中分配一些数据,但不知何故我的代码没有等待响应。基本上 console.log(this.newIds) 首先运行并且始终为空,因为订阅不等待来自后端的响应。我如何强制我的代码等待响应的到来?
this.repository.getById(Ids).subscribe((response) => {
console.log(response);
this.newIds = response.map((id) => {
return id;
});
});
console.log(this.newIds);
如果您将代码放在订阅回调中。它将在您收到 back-end 的响应后执行。您在该函数之外编写的所有代码都将直接执行。
this.repository.getById(Ids).subscribe((response) => {
//Code will execute when back-end will respond
console.log(response);
this.newIds = response.map((id) => {
return id;
});
console.log(this.newIds);
});
//Code will execute immediately
另请参阅:https://angular.io/guide/observables#creating-observables
这是正常行为,因为您的 console.log(this.newIds);
在订阅之外,您只需要将它移到 .subscribe() 方法中:
this.repository.getById(Ids).subscribe((response) => {
console.log(response);
this.newIds = response.map((id) => {
return id;
});
console.log(this.newIds);
});
如果你想在订阅之外使用 this.newIds 并在观察者的结果之后立即使用,你可以使用 RxJs .toPromise() 将其用作承诺并将方法更改为异步:
async callerFn(){
const response = await this.repository.getById(Ids).toPromise();
this.newIds = response.map((id) => {
return id;
});
console.log(this.newIds);
// use your property here
}
是的,因为 Javascript 正在解释 line-by-line 执行,因此它不会等待其他进程完成。这就是为什么最后一个控制台将 return 未定义的原因。同时,如果您使用订阅者内部的控制台,那么您将获得正确的日志,因为订阅者将等待响应并将其与 this.newIds
绑定 this.repository.getById(Ids).subscribe((response) => {
console.log(response);
this.newIds = response.map((id) => {
return id;
});
console.log(this.newIds);
});
在这里,我附上了一篇关于可观察订阅的好读物
https://betterprogramming.pub/observables-vs-promises-which-one-should-you-use-c19aef53c680
除此之外,如果您想在订户范围之外使用 newIds 访问权限,请将 promise 与 async await 结合使用。这里我添加了一个示例
async getAsyncData() {
this.asyncResult = await this.httpClient.get<Employee>(this.url).toPromise();
console.log('No issues, I will wait until promise is resolved..');
}
我会以不同的方式处理:如果您必须重新映射值,您可以使用 map
运算符:
this.repository.getById(Ids)
.pipe(map(response) => response.map(id => id))
.subscribe((id) => {
console.log(response);
this.newIds = id;
});
实际上,我不明白为什么你需要映射一个你已经拥有的值,但我认为这是明确的解决方案。
你可以这样做..
您的组件文件如下所示
newIds: Observable<any> = of(this.id).pipe(
concatMap((id) =>
this.getId(id).pipe(map((data) => data.map((rowId) => rowId.id)))
)
);
getId(id: any) {
return of([{ id: 1 }, { id: 2 }, { id: 3 }]);
}
您的 html 文件如下所示,并使用异步管道进行订阅。在这里你可以使用 concateMap 管道 rxjs 运算符顺序调用 observable,然后将值赋给你的 newId 变量。
<pre>
{{ newIds | async }}
</pre>
现场演示linkStackblitz Link