【问题标题】:AngularJs : Callback or promise in a service using conditionsAngularJs:使用条件在服务中回调或承诺
【发布时间】:2015-06-04 09:16:16
【问题描述】:

我有一个特定的情况,我不确定是否应该实现回调或承诺。我对承诺完全陌生,刚刚开始理解它的概念。因此我不想陷入anti patterns

我还阅读并重新阅读了角度文档$q

这就是我想要实现的:

如果使用承诺:

OauthService.token().then(function(access_token){
    config.url = config.url+'?access_token='+access_token;
});

return config;

如果使用回调:

OauthService.token(function(access_token){
    config.url = config.url+'?access_token='+access_token;
});

return config;

Oauth 服务不仅仅是一个 http 请求,如果它实际上有一些条件可以让我认为我应该使用回调而不是承诺。

所以这里我的服务现在使用回调。

OauthService.js:

app.factory('OauthService', function($http, $localStorage) {

return {
    token : function(callback){

        // Get actual token
        access_token = $localStorage.getObject('access_token');
        // Get actual identity
        identity_token = $localStorage.getObject('identity_token');

        // IF no user logged
        if(isObjectEmpty(identity_token)){

            // IF access_token does NOT exist OR will expires soon
            if( isObjectEmpty(access_token) || Date.now() > (access_token.expires_at - (600*1000)) ){

                // Create an anonymous access_token
                $http
                    .get(domain+'/oauth/v2/token?client_id='+public_id+'&client_secret='+secret+'&grant_type=client_credentials')
                    .then(function (response) {

                        $localStorage.setObject('access_token', {
                            key: response.data.access_token,
                            type: 'anonymous',
                            expires_at: Date.now()+(response.data.expires_in*1000)
                        });

                        // return access token here
                        callback(response.data.access_token);

                    });
            }

        }
        // IF user is logged
        else{

            // IF access_token does NOT exist OR will expires soon OR is anonymous
            if( isObjectEmpty(access_token) || Date.now() > (access_token.expires_at - (600*1000)) || access_token.type == 'anonymous' ){
                // Create an access_token with an identity
                $http
                    .get(domain+'/oauth/v2/token?client_id='+public_id+'&client_secret='+secret+'&api_key='+identity_token+'&grant_type=http://oauth2.dev/grants/api_key')
                    .then(function (response) {

                        $localStorage.setObject('access_token', {
                            key: response.data.access_token,
                            type: 'identity',
                            expires_at: Date.now()+(response.data.expires_in*1000)
                        });

                        // return access token here
                        callback(response.data.access_token);

                    });
            }

        }

        // return access token here (if the previous token has not changed of type or expired)
        callback(access_token.key);

    }
};

})

那么,如果我宁愿选择承诺,我应该如何实现呢?

【问题讨论】:

    标签: javascript angularjs callback angular-promise


    【解决方案1】:

    在您的操作中设置条件与回调与承诺无关。普通回调是一种糟糕的异步操作方式,你应该尽可能使用 Promise。

    你可以重写你的 token 方法来使用这样的承诺:

    app.factory('OauthService', function($http, $localStorage, $q) {
        return {
            token : function(callback){
    
                // Get actual token
                access_token = $localStorage.getObject('access_token');
                // Get actual identity
                identity_token = $localStorage.getObject('identity_token');
    
                // IF no user logged
                if(isObjectEmpty(identity_token)){
    
                    // IF access_token does NOT exist OR will expires soon
                    if( isObjectEmpty(access_token) || 
                        Date.now() > (access_token.expires_at - (600*1000)) ){
    
                        // Create an anonymous access_token
                        return $http
                            .get(domain+'/oauth/v2/token?client_id='+public_id + 
                                 '&client_secret=' + secret + '&grant_type=client_credentials')
                            .then(function (response) {
                                $localStorage.setObject('access_token', {
                                    key: response.data.access_token,
                                    type: 'anonymous',
                                    expires_at: Date.now() + 
                                           (response.data.expires_in * 1000)
                                });
    
                                return response.data.access_token;
                            });
                    }
                }
    
                // IF user is logged
                else {
                    // IF access_token does NOT exist OR will expire soon OR is anonymous
                    if( isObjectEmpty(access_token) || 
                        Date.now() > (access_token.expires_at - (600*1000)) || 
                        access_token.type == 'anonymous' ){
    
                        // Create an access_token with an identity
                        return $http
                            .get(domain+'/oauth/v2/token?client_id='+public_id+'&client_secret='+secret + 
                                 '&api_key='+identity_token+'&grant_type=http://oauth2.dev/grants/api_key')
                            .then(function (response) {
                                $localStorage.setObject('access_token', {
                                    key: response.data.access_token,
                                    type: 'identity',
                                    expires_at: Date.now()+
                                          (response.data.expires_in * 1000)
                                });
    
                                return response.data.access_token;    
                            });
                    }
    
                }
    
                // return access token here (if the previous token has not changed of type or expired)
                return $q.when(access_token.key);    
            }
        };
    });
    

    然后您可以进行一些重构以将其简化为:

    app.factory('OauthService', function($http, $localStorage, $q) {
        function expiresSoon(access_token) {
            return Date.now() > (access_token.expires_at - (600*1000));
        }
    
        function getAccessToken(url, type) {
            return $http
                .get(url)
                .then(function (response) {
                    $localStorage.setObject('access_token', {
                        key: response.data.access_token,
                        type: type,
                        expires_at: Date.now() + 
                            (response.data.expires_in * 1000)
                });
    
                    return response.data.access_token;
                });
        }
    
        return {
            token : function(callback){
    
                // Get actual token
                access_token = $localStorage.getObject('access_token');
                // Get actual identity
                identity_token = $localStorage.getObject('identity_token');
    
                // IF no user logged
                if(isObjectEmpty(identity_token)){
    
                    // IF access_token does NOT exist OR will expires soon
                    if( isObjectEmpty(access_token) || expiresSoon(access_token) ) {
                        var url = domain + '/oauth/v2/token?client_id=' + public_id + 
                                  '&client_secret=' + secret + '&grant_type=client_credentials';
                        // Create an anonymous access_token
                        return getAccessToken(url, 'anonymous');
                    }
                }
    
                // IF user is logged
                else {
                    // IF access_token does NOT exist OR will expire soon OR is anonymous
                    if( isObjectEmpty(access_token) || 
                        expiresSoon(access_token) || 
                        access_token.type == 'anonymous' ){
    
                        var url = domain+'/oauth/v2/token?client_id=' + public_id+
                                  '&client_secret='+secret + 
                                  '&api_key='+identity_token + 
                                  '&grant_type=http://oauth2.dev/grants/api_key';
    
                        // Create an access_token with an identity
                        return getAccessToken(url, 'identity');
                    }
                }
    
                // return access token here (if the previous token has not changed of type or expired)
                return $q.when(access_token.key);    
            }
        };
    });
    

    【讨论】:

    • 谢谢!这是完美的工作。自从我读到“这是最常见的反模式。当你不真正理解 Promise 并将它们视为美化的事件发射器或回调实用程序时,很容易陷入这种状态。”。
    猜你喜欢
    • 2013-07-22
    • 1970-01-01
    • 2019-09-20
    • 1970-01-01
    • 1970-01-01
    • 2015-04-08
    • 2014-11-17
    • 2015-01-30
    • 2012-08-20
    相关资源
    最近更新 更多