2016-12-12 10 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

ほぼ[** never it it **](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は既にこれを行っています。たとえば、$ httpサービスなどで返されたPromiseをそのまま使用することができます。あなたの例は自分のものを作成したいときの良い例を示しています。

通常、$ httpサービスはサーバーから値を返します。http呼び出しが失敗するとエラーが発生します。しかし、あなたの例では、http呼び出し自体が成功したときにPromise(=拒否)からエラーを返したいが、successプロパティの値が真ではない。

これを行うには、戻り値(またはエラー)を手動で制御できる新しいPromiseを作成します。この例では、httpコールが成功し、data.success == trueを持つ場合にのみresolve()(=値を返す)関数を呼び出します。他のすべての場合(http呼び出しが失敗したか、正しいdata.status値を持たない場合)、新しく作成されたPromiseは拒否されます(=リターンエラー)。

1

$q.defer()を使用すると、login関数を呼び出した関数に返すことのできる約束オブジェクトを作成できます。

はあなたの繰延オブジェクトを作成しただけで機能がそれにresolve()またはreject()を呼び出すことができるようにあなたが全体ではなくdeferredオブジェクトよりもdeferred.promiseを返すことを確認したが、約束が成就されるためにloginの呼び出し元の関数は、まだ待つことができます。理にかなっている?

+0

がきちんと説明されています。これはまさにそれがすることです –

関連する問題