Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Angular 2服务:返回局部变量或执行承诺_Javascript_Angular - Fatal编程技术网

Javascript Angular 2服务:返回局部变量或执行承诺

Javascript Angular 2服务:返回局部变量或执行承诺,javascript,angular,Javascript,Angular,我只想打一次电话。如果调用已经完成,我需要返回局部变量 服务: public currentUser: User; getUser() { if (this.currentUser) { return this.currentUser; } else { return this.http.get('/api/user/') .toPromise() .then(response =>

我只想打一次电话。如果调用已经完成,我需要返回局部变量

服务:

public currentUser: User;

getUser() {
    if (this.currentUser) {
        return this.currentUser;
    }
    else {
        return this.http.get('/api/user/')
            .toPromise()
            .then(response => {
                this.currentUser = response.json() as User;
                return this.currentUser;
            });
    }
}
如果用户为null,则调用将完成,但不会在组件中检索,因为调用是异步的。我怎样才能做到这一点

我在组件中尝试了这一点:

getUserFromService() {
    let serviceReturn = this.userService.getUser();

    if (serviceReturn instanceof User) {
        this.user = serviceReturn;
    }
    else {
        let promise = serviceReturn as Promise<User>;
        promise.then(
            response => {
                this.user = response;
            }
        );
    }
}
getUserFromService(){
让serviceReturn=this.userService.getUser();
if(用户的serviceReturn实例){
this.user=serviceReturn;
}
否则{
让承诺=服务作为承诺回报;
我保证,那么(
响应=>{
this.user=响应;
}
);
}
}

它第一次工作,但第二次,它没有将serviceReturn识别为用户,并转到引发错误的
else
。我认为这不是一个好办法,它一定是一个更好的办法。

但你会得到两种不同的回报类型,
Promise
User
。然后,您的服务消费者将始终必须确保他们收到的是哪种服务。最好总是返回一个
承诺

private currentUser: Promise<User>;

getUser() {
    if (!this.currentUser) {
        this.currentUser = this.http
           .get('/api/user/')
           .map(r => r.json())
           .toPromise();
    } 
    return this.currentUser;
}

在对
async/await
之类的东西进行了一番研究之后,我认为在服务内部使用
async/await
并将currentUser作为实际的
用户
而不是
承诺也可以:

private currentUser: Promise<User>;

getUser() {
    if (!this.currentUser) {
        this.currentUser = this.http
           .get('/api/user/')
           .map(r => r.json())
           .toPromise();
    } 
    return this.currentUser;
}
方法
getUser()
现在总是返回一个
Promise

我认为,这样代码的可读性更好一些。缺点很明显,在服务中,您可能也应该使用
getUser()
,而不是直接使用
currentUser

您确定您从
this.http.get
获得了承诺吗?是的,我忘了问题中的那一行,刚刚做了一个编辑:)这应该可以,但我更喜欢另一个答案带有
Promise.resolve()
@Robouste。另一个答案有一个小小的设计缺陷,如果您调用该方法两次,并且它没有第一次返回,它将对服务器执行相同的请求两次。我的回答没有产生如此可怕的后果。我注意到,当两个不同的组件在同一页面上调用服务时,用户被加载了两次,这并不方便。然后我会尝试这个解决方案。我尝试了这个答案,但我的IDE(VSCode)无法识别单词
wait
。我应该从哪里导入它?您应该将
TypeScript
更新到至少2.1。这就是引入
async/await
的时候。您还应该将方法标记为
async
。我会更新我的答案
doSomething(): any {
    this.userService.getUser().then((user: User) => {

    });
 }
private currentUser: User;

async getUser() {
    if (!this.currentUser) {
        this.currentUser = await this.http
            .get('/api/user/')
            .map(r => r.json());
    } 
    return this.currentUser;
}