2016-10-15 30 views
0

我在我的Angular2 /火力侧项目工作,并停止在该块的代码一段时间。我想在这里做的是创建signupUser方法的新帐户,然后,只有当它成功,调用另一个方法saveNewUserInDatabase。如果我像下面这样做,方法router.navigate不会等待5秒钟。如何做好JavaScript的承诺更优雅的方式链接?

//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); 
     }); 
    } 

但是,如果我嵌套.then方法就像下面的例子,它工作,因为我希望工作。

//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秒到/映射路径后导航)。尽管如此,我并不认为在承诺中嵌套承诺是一种好的做法。我如何链接这里的承诺,如

.then() 
.then() 

并使第二个。然后在第一个完成后触发?

感谢您的帮助提前。

+0

你希望你的链条,等待那些'setTimeout's?那么你需要使用承诺。 – Bergi

+0

确实saveNewUserInDatabase返回一个承诺? – helsont

回答

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) 
     }); 
    } 
+0

我所读过的东西上的承诺和玩你的解决方案。 “新承诺”之前的唯一一个实际缺少的是'return'关键字。这实际上是我试图达到的目标。 –

+0

感谢您的帮助! –

+0

你可能会考虑接受的答案 –

2

您可以创建一个延时功能,你可以管到你的诺言链。

//EXAMPLE 2 
 

 
function delay(time) { 
 
    return new Promise((resolve, reject) => { 
 
    setTimeout(resolve, time) 
 
    }) 
 
} 
 

 
function onSignup() { 
 
    this.authService.signupUser(this.signupForm.value) 
 
    .then(response => { 
 
    const userObject = { 
 
     uid: response.auth.uid, 
 
     email: response.auth.email 
 
    } 
 
    return userObject 
 
    }) 
 
    .then(this.authService.saveNewUserInDatabase) 
 
    .then(delay(5000)) 
 
    .then(() => { 
 
    this.router.navigate(['/map']) 
 
    }) 
 
    .catch(error => { 
 
    console.log(error) 
 
    }); 
 
}

+0

您仍然需要一个回调传递给'then',虽然 – Bergi

+0

也许我没有让自己在描述清楚的setTimeout方法是在调试的目的只是我的助手功能。我并不需要任何延迟。 Gabriel的解决方案对我很好。尽管谢谢你的时间! –