vai*_*akh 3 javascript asynchronous promise observable rxjs
对 Angular 相当陌生,并且在 Promises、Observables 和 async/await 方面遇到困难。
然而,这似乎不起作用。我感觉这与 Observables/subscribe 的工作方式有关,但我无法解决它。
代码片段:
initPage() {
fetchCurrentUserDetails().then((user) => { //tasks dependent on current user
//task 1
//task 2
});
}
fetchCurrentUserDetails(): Promise<any> {
return Promise.resolve((async () => {
let currentUser = this.global.getUser();// check if user is defined already
let userId: string = sessionStorage.getItem('userid');
if (currentUser == undefined) {
let initProfile = new Promise(resolve => resolve(this.fetchDetailsFromDB(userId)));
const profile: any = await initProfile; //Waits, but returns before the Observable comes back
let user = new User();
// initialize user with the fetched values
user.id = profile.id; // Undefined, since value not returned yet
user.name = profile.user_name; // Undefined, since value not returned yet
// Set this user in a global variable
this.global.setUser(user);
}
return this.global.getUser();
})());
}
fetchDetailsFromDB(userId: string) {
//callProfileService has nothing but the http.get statement
this.callProfileService(userId).subscribe((response) => {
let profile = response.body.response.data.user;
return profile;
});
}
Run Code Online (Sandbox Code Playgroud)
编辑:添加我如何尝试使用 toPromise:
fetchDetailsFromDB(userId: string) {
this.callUserProfileService(userId).toPromise().then((response) => {
let profile = response.body.response.data.user;
return profile;
});
Run Code Online (Sandbox Code Playgroud)
这是正确的方法吗?如果是这样,如何让await等待Observable返回?
事实上,您需要该toPromise()方法,但不要忘记返回该承诺(return回调中的 还不够——该函数fetchDetailsFromDB需要返回一个承诺)。
在代码的其余部分:这是一种反模式,可以使用Promise.resolve,new Promise就像这样:根据经验,当您已经有一个可以使用的承诺(例如,来自 API 函数调用)时,不要使用其中任何一个创建新的承诺)。
因此,您可以使用方法来做到这一点async:
async fetchCurrentUserDetails(): Promise<any> {
//^^^^
let currentUser = this.global.getUser();
if (currentUser == undefined) {
const userId: string = sessionStorage.getItem('userid');
const profile: any = await this.fetchDetailsFromDB(userId);
currentUser = new User();
currentUser.id = profile.id;
currentUser.name = profile.user_name;
this.global.setUser(currentUser);
}
return currentUser;
}
async fetchDetailsFromDB(userId: string): Promise<any> {
const response = await this.callUserProfileService(userId).toPromise();
return response.body.response.data.user;
};
Run Code Online (Sandbox Code Playgroud)