2016-12-12 2 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() для создания нового обещания.

В большинстве случаев Angular уже сделал это за вас, и вы можете просто использовать обещание, которое возвращается, например, службой $ http. Ваш пример показывает хороший пример того, когда вы хотите создать свой собственный.

Как видите, обычно служба $ http возвращает значение с сервера или сообщение об ошибке при неудаче HTTP-вызова. В вашем примере, однако, вы также хотите вернуть ошибку из Promise (= отклонить ее), когда сам http-вызов, но имеет неверное значение для свойства success.

Для этого в примере создается новое обещание, возвращаемое значение которого (или ошибка) можно вручную контролировать. В этом примере, вызвав функцию resolve() (= вернуть значение) только тогда, когда http-вызов успешный и имеет data.success == true. Во всех остальных случаях (когда HTTP-вызов терпит неудачу или не имеет правильного значения data.status), вновь созданная Promise отвергается (= обратная ошибка).

1

$q.defer() позволяет создать объект обещания, который вы, возможно, захотите вернуться к функции, вызвавшей вашу функцию login.

Убедитесь, что вы вернетесь deferred.promise, а не весь deferred объект так, что только функция, которая создала свой отложенный объект можно назвать resolve() или reject() на него, но функция Призвание login еще может ждать обещание будет выполнено. Имеют смысл?

+0

приятно объяснил. Это именно то, что он делает –

Смежные вопросы