2016-12-12 33 views
2

我是Angularjs的新手,我遵循本教程:http://mherman.org/blog/2015/07/02/handling-user-authentication-with-the-mean-stack/#.WE70iubhCM8。不過,我不明白何時使用$ q.defer()。例如,在folllowing Angularjs代碼爲什麼使用$ q.defer():

function login(username, password) { 

     // create a new instance of deferred 
     var deferred = $q.defer(); 

     // send a post request to the server 
     $http.post('/user/login', 
     {username: username, password: password}) 
     // handle success 
     .success(function (data, status) { 
      if(status === 200 && data.status){ 
      user = true; 
      deferred.resolve(); 
      } else { 
      user = false; 
      deferred.reject(); 
      } 
     }) 
     // handle error 
     .error(function (data) { 
      user = false; 
      deferred.reject(); 
     }); 

服務器端代碼:

router.post('/login', function(req, res, next) { 
    passport.authenticate('local', function(err, user, info) { 
    if (err) { 
     return next(err); 
    } 
    if (!user) { 
     return res.status(401).json({ 
     err: info 
     }); 
    } 
    req.logIn(user, function(err) { 
     if (err) { 
     return res.status(500).json({ 
      err: 'Could not log in user' 
     }); 
     } 
     res.status(200).json({ 
     status: 'Login successful!' 
     }); 
    }); 
    })(req, res, next); 
}); 

爲什麼下面的代碼Angularjs不使用它:

function getUserStatus() { 
     return $http.get('/user/status') 
     // handle success 
     .success(function (data) { 
     if(data.status){ 
      user = true; 
     } else { 
      user = false; 
     } 
     }) 
     // handle error 
     .error(function (data) { 
     user = false; 
     }); 
    } 

服務器端代碼:

router.get('/status', function(req, res) { 
    if (!req.isAuthenticated()) { 
    return res.status(200).json({ 
     status: false 
    }); 
    } 
    res.status(200).json({ 
    status: true 
    }); 
}); 
+1

幾乎[**從不使用它**](http://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it) !不要從這個例子中學習,它使用了一個廣爲人知的反模式。 – Bergi

回答

7

簡單地說,你可以使用$ q.defer()來創建一個Promise。 Promise是函數,它將在未來返回單個值或錯誤。所以,只要你有一個應該返回一個值或一個錯誤的異步進程,你可以使用$ q.defer()來創建一個新的Promise。

儘管在大多數情況下,Angular已經爲你做了這個,你可以簡單地使用返回的Promise,例如通過$ http服務。你的例子顯示了你想創建自己的時間的一個很好的例子。

您會看到,通常情況下,$ http服務返回來自服務器的值,或者當http調用失敗時返回錯誤。在你的例子中,你也想從Promise返回一個錯誤(=拒絕它),當http調用成功時,但是對於success屬性有一個非真值。

爲此,該示例創建了一個新的Promise,它的返回值(或錯誤)可以手動控制。在這個例子中,只有當http調用成功並且具有data.success == true時,才調用resolve()(=返回值)函數。在所有其他情況下(當http調用失敗或沒有正確的data.status值時),新創建的Promise被拒絕(=返回錯誤)。

1

$q.defer()允許您創建一個承諾對象,您可能想要返回到調用您的login函數的函數。

確保您返回deferred.promise而不是整個deferred對象,這樣只有創建您的延期對象的函數可以調用它resolve()reject(),但login調用函數仍然可以等待履行承諾。合理?

+0

很好解釋。這正是它所做的 –

相關問題