Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
AngularJS回调流_Angularjs_Cordova_Ionic Framework - Fatal编程技术网

AngularJS回调流

AngularJS回调流,angularjs,cordova,ionic-framework,Angularjs,Cordova,Ionic Framework,我们正在使用AngularJS和Ionic框架创建一个基于PhoneGap的应用程序 此应用程序是一个商店管理系统,它与使用OAuth2的现有web应用程序连接 该应用程序包括一个“订单”视图,其中显示客户已收到的订单列表。在加载订单列表之前,以下函数验证用户的访问令牌是否仍然有效,如果无效,则获取一个新的令牌 function verifyAccessToken() { var now = new Date().getTime(); if

我们正在使用AngularJS和Ionic框架创建一个基于PhoneGap的应用程序

此应用程序是一个商店管理系统,它与使用OAuth2的现有web应用程序连接

该应用程序包括一个“订单”视图,其中显示客户已收到的订单列表。在加载订单列表之前,以下函数验证用户的访问令牌是否仍然有效,如果无效,则获取一个新的令牌

function verifyAccessToken() {


            var now = new Date().getTime();

            if (now > tokenStore.access_token_expiry_date) {

                // renew access token
                $http({
                    url: '*API URL*/token',
                    method: "POST",
                    data: { 
                        refresh_token : tokenStore.refresh_token,
                        grant_type : 'refresh_token',
                        client_id: clientId,
                        client_secret: clientSecret,
                        redirect_uri: redirectURI 
                    },
                    headers: {'Content-Type': 'application/x-www-form-urlencoded'},
                    transformRequest: function(obj) {
                        var str = [];
                        for(var p in obj)
                        str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
                        return str.join("&");
                    }                       
                })
                .success(function (data, status, headers, config) {
                    tokenStore['access_token'] = data.access_token;
                    var expiresAt = now + parseInt(data.expires_in, 10) * 1000 - 10000;
                    tokenStore['access_token_expiry_date'] = expiresAt;
                    console.log(data.access_token);
                })
                .error(function (data, status, headers, config) {
                    if(status=='404') {
                        $rootScope.$emit('serviceUnavailable');
                    }
                    if(status=='400' || status=='401') {
                        $rootScope.$emit('tokenUnauthorized');
                    }
                    console.log(status);
                    console.log(data);          
                }); 
            } 


        };
然后,它使用新的访问令牌调用订单列表

return $http({method: 'GET', url: '*API URL*?access_token=' + tokenStore.access_token, params: {}})
                .error(function(data, status, headers, config) {
                    if(status=='404') {
                        $rootScope.$emit('serviceUnavailable');
                    }
                    if(status=='401') {
                        $rootScope.$emit('tokenUnauthorized');
                    }
                    console.log(status);
                    console.log(data);  
                });     
        }
问题在于HTTP GET不会等待VerifyAccessToken函数完成

如何构建此结构以避免此问题

如果您能提供任何建议,我们将不胜感激

在klyd的回答后更新2:

我已经更新了oauth-angular.js中的两个函数,如下所述:

verifyAccessToken函数现在的内容如下:

    function verifyAccessToken() {
        var deferred = $q.defer();

        if ( (new Date().getTime()) < tokenStore.access_token_expiry_date ) {
            /* token is still valid, resolve the deferred and bail early */
            deferred.resolve();
            return deferred.promise;
        }

        /* token is not valid, renew it */
        alert('getting new access token')
        $http({
            url: 'https://' + tokenStore.site_name + '.somedomain.com/api/oauth2/token',
            method: "POST",
            data: { 
                refresh_token : tokenStore.refresh_token,
                grant_type : 'refresh_token',
                client_id: clientId,
                client_secret: clientSecret,
                redirect_uri: redirectURI 
            },
            headers: {'Content-Type': 'application/x-www-form-urlencoded'},
            transformRequest: function(obj) {
                var str = [];
                for(var p in obj)
                str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
                return str.join("&");
            }                       
        }).success(function (data, status, headers, config) {
            tokenStore['access_token'] = data.access_token;
            var now = new Date().getTime();
            var expiresAt = now + parseInt(data.expires_in, 10) * 1000 - 10000;
            tokenStore['access_token_expiry_date'] = expiresAt;
            console.log(data.access_token);
            deferred.resolve();
        })
        .error(function (data, status, headers, config) {
            if(status=='404') {
                $rootScope.$emit('serviceUnavailable');
            }
            if(status=='400' || status=='401') {
                $rootScope.$emit('tokenUnauthorized');
            }
            console.log(status);
            console.log(data);
            deferred.reject(); // as the last step, reject the deferred, there was a failure
        });

        return deferred.promise;
    }
function getOrders() {

         verifyAccessToken().then(
            function() {
                return $http({method: 'GET', url: 'https://' + tokenStore.site_name + '.somedomain.com/api/1.0/orders?access_token=' + tokenStore.access_token, params: {}})
                    .error(function(data, status, headers, config) {
                        if(status=='404') {
                            $rootScope.$emit('serviceUnavailable');
                        }
                        if(status=='401') {
                            $rootScope.$emit('tokenUnauthorized');
                        }
                        console.log(status);
                        console.log(data);  
                    });
            },
            function() {
                /* code to handle a failure of renewing the token */
            });

    }
现在,我的controllers.js文件在执行函数getOrders时抛出以下错误

TypeError:无法读取未定义的属性“success”

这以前是没有问题的。有什么想法吗?

的返回值是。每当函数返回一个承诺时,它最有可能执行异步操作。这意味着函数调用将立即返回一个对象,当该操作完成时,您可以使用该对象调用其他方法

在这种情况下,您应该重新安排verifyAccessToken函数,以返回它自己的承诺

比如:

function verifyAccessToken() {
    var deferred = $q.defer();

    if ( (new Date().getTime()) < tokenStore.access_token_expiry_date ) {
        /* token is still valid, resolve the deferred and bail early */
        deferred.resolve();
        return deferred.promise;
    }

    /* token is not valid, renew it */
    $http({
        /* stuff */
    }).success(function() {
        /* stuff */
        deferred.resolve(); // resolve the deferred as the last step
    })
    .error(function() {
        /* stuff */
        deferred.reject(); // as the last step, reject the deferred, there was a failure
    });

    return deferred.promise;
}
/* stuff before the verifyAccessToken call */
verifyAccessToken().then(
    function() {
        /* any stuff after the verifyAccessToken call */
        /* or any code that was dependent on verifying the access token */
    },
    function() {
        /* code to handle a failure of renewing the token */
    });
/*
     there should be nothing after the call that depends on verifying the
     access token. Remember this asynchronous so the initial call to verifyAccessToken
     is going to return immediately. Then sometime in the future the success
     or error call back will be called.
*/

您还没有发布足够的代码。例如,verifyAccessToken实际在哪里调用?它是在哪里定义的?它有$http/$rootScope,但没有直接注入任何内容,它是在闭包中吗?你能把一个简化的JSFIDLE或plunkr放在一起说明力学原理吗?另外,您应该再次查看我的示例,您的示例声明了延迟变量,但对它没有任何作用。很抱歉,这一天太长了。我已经更新了上面的代码,希望现在你就快到了。看看getOrders函数,它不会立即返回任何内容,这就是为什么没有成功方法的原因。您需要返回getOrders中的verifyAccessToken行。在这之后,您需要从.success和.error更改为对.的调用,然后error和success是HttpPromise的特殊功能。您是对的,如果我们这样做,我们将开始完成一些工作。是否有办法组织它,以便我们继续将成功/错误反馈给控制员?那么,当前控制器逻辑工作了吗?我们尝试在getOrders中包装延迟逻辑,但没有成功。我们认为我们可以在verifyAccessToken之前添加return,它会像以前一样出现在控制器上。这可能是最好的使用方法。然后使用符号,因为它与所有承诺兼容,包括$http返回的承诺。但如果您确实必须有.success和.error,那么您可以将承诺存储在变量getOrders中,并添加这两个函数,然后返回它。请在此处查看$http的.success/.error实现:
/* stuff before the verifyAccessToken call */
verifyAccessToken().then(
    function() {
        /* any stuff after the verifyAccessToken call */
        /* or any code that was dependent on verifying the access token */
    },
    function() {
        /* code to handle a failure of renewing the token */
    });
/*
     there should be nothing after the call that depends on verifying the
     access token. Remember this asynchronous so the initial call to verifyAccessToken
     is going to return immediately. Then sometime in the future the success
     or error call back will be called.
*/