2016-10-15 32 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的解決方案對我很好。儘管謝謝你的時間! –