是否使用promises或使用$ http调用

时间:2016-05-20 07:40:37

标签: javascript angularjs ionic-framework

我无法弄清楚我应该使用我的代码以及如何使用promises。用我的$ http电话。

我有以下功能

首先我要打电话

$scope.getAcessToken()

一旦我获得了访问令牌,我将进行以下调用

$scope.getDataSets(lastSaved, cTime, accessToken)

这两个功能如下:

$scope.getAcessToken = function()
  {
    alert("inside getAcessToken function");
    refreshToken = localStorage.getItem("refreshToken");
    if(refreshToken)
    {
      $http({
            method: "post", url: "https://accounts.google.com/o/oauth2/token", 
            data: "client_secret=" + clientSecret + "&grant_type=refresh_token" + "&refresh_token="+ refreshToken + "&client_id=" + clientId  
              })
      .success(function(data){
            accessToken = data.access_token;
      })
      .error(function(data,status){
        alert("ERROR: " + JSON.stringify(data) + status);
      });
    }
    else
    {
      $scope.firstTimeAuth();
    }
    return accessToken;
  }

$scope.getDataSets = function(startTime, endTime, accessToken, )
  {
    $scope.a = "inside dataSets function";
    $url = "https://www.googleapis.com/fitness/v1/users/me/dataSources/derived:com.google.step_count.delta:com.google.android.gms:estimated_steps/datasets/" + startTime +"000000"+"-"+ endTime + "000000"; 
    alert("acess token is " + accessToken );
    if(accessToken != "")
    {
        $http({method: 'GET', url: $url,
                        headers: {'Authorization': 'OAuth ' + accessToken},               
            })
            .success(function(response){
                alert("inside success block datasets");
                $scope.handleResponse(response);
            })
            .error(function(response) {
                alert("Something went wrong" + JSON.stringify(response));
            });
        }
        else
        {
            alert("no access token received");
        }
  }

因此,在我真正获得访问令牌之前,先获取数据集 怎么预防呢? 编辑1:

$scope.firstTimeAuth = function(callback) {
      var ref = window.open('https://accounts.google.com/o/oauth2/auth?client_id=' + clientId + '&redirect_uri=http://localhost/callback&scope=https://www.googleapis.com/auth/fitness.activity.write &approval_prompt=force&response_type=code&access_type=offline', '_blank', 'location=no');
      ref.addEventListener('loadstart', function(event) {

        if((event.url).startsWith("http://localhost/callback")) {
            requestToken = (event.url).split("code=")[1];

            $http({
                method: "post", url: "https://accounts.google.com/o/oauth2/token", 
                data: "client_id=" + clientId + "&client_secret=" + clientSecret + "&redirect_uri=http://localhost/callback" + "&grant_type=authorization_code" + "&code=" + requestToken 
              })
              .success(function(data) {
                      accessToken = data.access_token;
                      refreshToken = data.refresh_token;
                      if(typeof(Storage) != "undefined") {
                          localStorage.setItem("refreshToken", refreshToken);
                          alert(localStorage.getItem("refreshToken"));
                      } else {
                          alert("Sorry, your browser does not support Web Storage...");
                      }
                      //$location.path("/secure");
                  })
               .error(function(data, status) {
                      alert("ERROR: " + data);
                  });
              ref.close();
          }
      });
      callback();
  }

2 个答案:

答案 0 :(得分:2)

你必须在$scope.getAcessToken函数中使用defer来使整个函数成为一个承诺。为了使其正常工作,您需要在控制器依赖项中添加$q。你的功能现在看起来像这样:

$scope.getAcessToken = function(){
        alert("inside getAcessToken function");
        refreshToken = localStorage.getItem("refreshToken");
        var deferred = $q.defer();
    if(refreshToken){
          $http({
                method: "post", url: "https://accounts.google.com/o/oauth2/token", 
                data: "client_secret=" + clientSecret + "&grant_type=refresh_token" + "&refresh_token="+ refreshToken + "&client_id=" + clientId  
                  })
          .success(function(data){
                accessToken = data.access_token;
                deferred.resolve(true);
          })
          .error(function(data,status){
               alert("ERROR: " + JSON.stringify(data) + status);
               deferred.resolve(true);
          });
        }
        else
        {
          $scope.firstTimeAuth();
        }
        return deferred.promise;
      }

现在您可以将此功能用作承诺,这样当完成后,请致电$scope.getDataSets

$scope.getAcessToken().then(function(){
    $scope.getDataSets();
});

答案 1 :(得分:1)

您必须使用angularjs提供的$ q服务来确保多个方法的调用序列。 ($q doc link

根据您的要求,下面是最可能实现的代码:

$scope.getAcessToken = function()
  {
    var deferral = $q.defer();

    alert("inside getAcessToken function");
    refreshToken = localStorage.getItem("refreshToken");
    if(refreshToken)
    {
      $http({
            method: "post", url: "https://accounts.google.com/o/oauth2/token", 
            data: "client_secret=" + clientSecret + "&grant_type=refresh_token" + "&refresh_token="+ refreshToken + "&client_id=" + clientId  
              })
      .success(function(data){
            deferral.resolve( { accessToken: data.access_token } );
      })
      .error(function(data,status){
        alert("ERROR: " + JSON.stringify(data) + status);
        deferral.reject( { accessToken: data.access_token, error:  JSON.stringify(data) + status} );
      });
    }
    else
    {
      $scope.firstTimeAuth();
    }
    return deferral.promise;
  }

  $scope.getDataSets = function(startTime, endTime, accessToken, )
  {
    $scope.a = "inside dataSets function";
    $url = "https://www.googleapis.com/fitness/v1/users/me/dataSources/derived:com.google.step_count.delta:com.google.android.gms:estimated_steps/datasets/" + startTime +"000000"+"-"+ endTime + "000000"; 
    alert("acess token is " + accessToken );
    if(accessToken != "")
    {
        $http({method: 'GET', url: $url,
                        headers: {'Authorization': 'OAuth ' + accessToken},               
            })
            .success(function(response){
                alert("inside success block datasets");
                $scope.handleResponse(response);
            })
            .error(function(response) {
                alert("Something went wrong" + JSON.stringify(response));
            });
        }
        else
        {
            alert("no access token received");
        }
  }


  // making sure that $scope.getDataSets will be called when $scope.getAcessToken() call is completed
  $q.when($scope.getAcessToken()).then(function(result) {
                     $scope.getDataSets(startTime, endTime, result.accessToken, );
                 });