何时在Angularjs中使用$ q.defer()

时间:2016-12-12 19:06:21

标签: javascript angularjs promise mean-stack

我是Angularjs的新手,我正在学习本教程:http://mherman.org/blog/2015/07/02/handling-user-authentication-with-the-mean-stack/#.WE70iubhCM8。但是我不明白何时使用$ q.defer()。例如,在下面的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
  });
});

2 个答案:

答案 0 :(得分:8)

简单地说,你可以使用$ q.defer()来创建一个Promise。 Promise是一个函数,在将来返回单个值或错误。所以每当你有一些应该返回值或错误的异步进程时,你可以使用$ q.defer()来创建一个新的Promise。

在大多数情况下,Angular已经为您完成了此操作,您只需使用返回的Promise,例如$ http服务。您的示例显示了您何时想要创建自己的示例。

您会看到,$ http服务通常会从服务器返回值,或者在http调用失败时返回错误。在您的示例中,您还希望在http调用本身成功时从Promise(=拒绝它)返回错误,但对success属性具有非true值。

为此,该示例创建一个新的Promise,然后可以手动控制其返回值(或错误)。在此示例中,仅在http调用成功并且具有resolve()时调用data.success == true(=返回值)函数。在所有其他情况下(当http调用失败或没有正确的data.status值时),新创建的Promise被拒绝(=返回错误)。

答案 1 :(得分:1)

$q.defer()允许您创建一个promise对象,您可能希望将其返回到调用login函数的函数。

确保返回deferred.promise而不是整个deferred对象,以便只有创建延迟对象的函数才能在其上调用resolve()reject(),但是login的调用函数仍然可以等待履行承诺。有意义吗?