[英]angular how to await subscribe
我是关于 Angular 应用程序的新手。 我不明白subscribe
是如何工作的。 我目前的阻碍是我不明白为什么在console.log("B")
之前执行console.log("A")
,因此呈现空数组的结果(请参阅console
输出的链接)。
我试图将所有代码放在一个带有async/await
的函数中以等待该函数。 我不明白为什么它不起作用。
在这种情况下等待订阅的最佳方式是什么?
console.log("B")
必须在console.log("A")
之后执行。
this._roleService.getRoleTypes(this.token).subscribe(
response => {
if(response.status != "error" && response.code != 400){
let _roleTypes:Array<RoleType> = new Array<RoleType>();
_roleTypes = new Array<RoleType>();
response.data.forEach(rt => {
let roleType:RoleType = new RoleType(
rt.id,
rt.name
);
_roleTypes.push(roleType);
});
console.log("A");
console.log(_roleTypes);
this.roleTypes = _roleTypes;
}
else{
this._loginService.destroySession();
}
},error => {
this.errorMessage = <any>error;
if(this.errorMessage != null){
console.log(this.errorMessage);
alert("Petition Error");
}
}
);
console.log("B");
console.log(this.roleTypes);
您可以使用 toPromise 方法实现此目的。 这也是处理异步操作的好方法。 只需删除订阅并添加此方法,并在调用此方法的方法中添加 async 关键字。
例子-
const response = await this._roleService.getRoleTypes(this.token).toPromise();
所以,现在你会先得到 console.log("A") 然后是 console.log("B")。
如果您需要同步执行代码,则应使用 async/await。 将您的订阅代码包装在一个返回承诺的函数中。
async getRolestypes(): Promise<Array<RoleType>> {
return new Promise((resolve, reject) => {
this._roleService.getRoleTypes(this.token).subscribe(
response => {
if(response.status != "error" && response.code != 400){
let _roleTypes:Array<RoleType> = new Array<RoleType>();
_roleTypes = new Array<RoleType>();
response.data.forEach(rt => {
let roleType:RoleType = new RoleType(
rt.id,
rt.name
);
_roleTypes.push(roleType);
});
console.log("A");
console.log(_roleTypes);
resolve(_roleTypes);
}
else{
this._loginService.destroySession();
reject('not a good response')
}
},error => {
this.errorMessage = <any>error;
if(this.errorMessage != null){
reject(this.errorMessage);
}
}
);
})
}
this.roleTypes = await getRolestypes();
console.log(this.roleTypes);
您可能知道,订阅用于处理异步方法调用。 因此,仅当异步方法返回其结果(例如在 http 调用之后)时,才会执行 subscribe() 方法中的代码。
在等待异步响应时,程序继续执行以下代码。 这就是异步调用的目标!
这就是为什么您的console.log('B')
在您的console.log('A')
之前执行。
下面是一个例子:
this.myservice.asyncCall().subscribe( (result) => {
// wait for the async response
console.log('I get some data from asyncCall()');
});
// sync code executed, even if the previous async call doesn't respond anything
console.log('Code executed after the subscription. But not waiting for it to respond');
如果你想要你是console.log('B')
,你必须把它移到你的订阅函数中(在 else 语句之后)。 您还可以从该位置调用方法,具体取决于您要查找的目的。
你也可以看看.map()
方法。 这允许您在 subscribe 方法中处理检索到的响应之前对其进行编辑(添加一些数据、转换它、记录或其他任何内容)。
上面的@sunny 答案是我的首选。 但是toPromise
在 RxJs 7 中已被弃用,并且在 RxJs 8 发布时可能不会出现。 所以新的方法是:
import { lastValueFrom } from 'rxjs';
const roleTypes$ = this._roleService.getRoleTypes(this.token);
const response = await lastValueFrom(roleTypes$);
subscribe 是异步执行的。 在您的情况下, subscribe 将执行,然后 console.log('B') 将在此之后执行。 稍后,当 Observable 发布响应(基于成功/错误)时,将调用相应的成功/错误回调。 所以你可以在成功回调中处理 console.log('B')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.