我是角度应用的新手。我不明白订阅的确切方式。我在这种情况下的问题是我不明白为什么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);
答案 0 :(得分:8)
您可以使用 toPromise 方法实现此目的。这也是处理异步操作的好方法。只需删除订阅并添加此方法,并在调用此方法的方法中添加 async 关键字。
示例-
const response = await this._roleService.getRoleTypes(this.token).toPromise();
所以,现在你会先得到 console.log("A") 然后是 console.log("B")。
答案 1 :(得分:3)
如果需要同步执行代码,则应使用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);
答案 2 :(得分:2)
您可能知道,订阅用于处理异步方法调用。因此,subscribe()方法中的代码仅在异步方法返回其结果时(例如在http调用之后)执行。
在等待异步响应时,程序继续执行以下代码。这是异步调用的目标!
这就是您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()
方法。这允许您在订阅方法中处理它之前编辑检索到的响应(添加一些数据,转换它,记录或任何东西)。
答案 3 :(得分:0)
订阅以异步方式执行。在您的情况下,订阅将执行,然后console.log('B')将在此之后执行。在稍后的时间点,Observable发布响应(基于成功/错误),将调用相应的成功/错误回调。所以你可以在成功回调中处理console.log('B')