怎么做javascript承诺以更优雅的方式链接?

时间:2016-10-15 18:04:28

标签: javascript firebase promise firebase-authentication

我在Angular2 / firebase端项目上工作,并在这段代码上停了一会儿。我在这里尝试做的是使用signupUser方法创建一个新帐户,然后,只有在成功时,调用另一个方法saveNewUserInDatabase。如果我像下面那样,方法router.navigate不会等待5秒。

    //EXAMPLE 1

    public onSignup(): void {
    this.authService.signupUser(this.signupForm.value)
        .then(response => {
            let userObject = {
                uid: response.auth.uid,
                email: response.auth.email
            };

            setTimeout(() => this.authService.saveNewUserInDatabase(userObject) , 5000)})
        .then(() => {
                setTimeout(() => { this.router.navigate(['/map'])}, 1500);
        })
        .catch(error => {
            console.log(error);
        });
    }

但是,如果我嵌套。然后像下面的例子那样的方法,它就像我希望的那样工作。

//EXAMPLE 2

public onSignup(): void {
    this.authService.signupUser(this.signupForm.value)
        .then(response => {
            let userObject = {
                uid: response.auth.uid,
                email: response.auth.email
            };

            setTimeout(() => this.authService.saveNewUserInDatabase(userObject)
                .then(() => {
                        setTimeout(() => { this.router.navigate(['/map'])}, 1500);
                    }
                ), 5000)
        })
        .catch(error => { 
             console.log(error)
        });
}

服务方法

public signupUser(user: UserLogin): firebase.Promise<FirebaseAuthState> {
    return this.af.auth.createUser({email : user.email, password: user.password});
}

public saveNewUserInDatabase(user): firebase.database.ThenableReference {
    return firebase.database().ref().child("users").push(user);
}

第二种解决方案有效(用户在5秒后导航到/ map路径)。尽管如此,我并不认为嵌套承诺是一种好的做法。我怎样才能在这里链接承诺,如

.then()
.then()

然后做第二次。然后在第一次完成后触发?

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

您可以创建一个延迟函数,您可以将其传递到您的保证链。

{{1}}

答案 1 :(得分:0)

要按照你的意愿去做,你需要在第一个时间内返回一个承诺:

public onSignup(): void {
    this.authService.signupUser(this.signupForm.value)
        .then(response => new Promise(function (resolve, reject) {
             let userObject = {
                 uid: response.auth.uid,
                 email: response.auth.email
              };
              setTimeout(() => resolve(this.authService.saveNewUserInDatabase(userObject)), 5000)  
        })
        .then( () => {
            setTimeout(() => { this.router.navigate(['/map'])}, 1500)
        })
        .catch(error => { 
         console.log(error)
        });
   }