I really don't like the fact that, because of the "promise" way of doing things, the consumer of the service that uses $http has to "know" about how to unpack the response. 
I just want to call something and get the data out, similar to the old $scope.items = Data.getData(); way, which is now deprecated.
I tried for a while and didn't come up with a perfect solution, but here's my best shot (Plunker). It may be useful to someone.
app.factory('myService', function($http) {
  var _data;  // cache data rather than promise
  var myService = {};
  myService.getData = function(obj) { 
    if(!_data) {
      $http.get('test.json').then(function(result){
        _data = result.data;
        console.log(_data);  // prove that it executes once
        angular.extend(obj, _data);
      }); 
    } else {  
      angular.extend(obj, _data);
    }
  };
  return myService;
}); 
Then controller:
app.controller('MainCtrl', function( myService,$scope) {
  $scope.clearData = function() {
    $scope.data = Object.create(null);
  };
  $scope.getData = function() {
    $scope.clearData();  // also important: need to prepare input to getData as an object
    myService.getData($scope.data); // **important bit** pass in object you want to augment
  };
});
Flaws I can already spot are
- You have to pass in the object which you want the data added to, which isn't an intuitive or common pattern in Angular 
- getDatacan only accept the- objparameter in the form of an object (although it could also accept an array), which won't be a problem for many applications, but it's a sore limitation
- You have to prepare the input object $scope.datawith= {}to make it an object (essentially what$scope.clearData()does above), or= []for an array, or it won't work (we're already having to assume something about what data is coming).  I tried to do this preparation step INgetData, but no luck.
Nevertheless, it provides a pattern which removes controller "promise unwrap" boilerplate, and might be useful in cases when you want to use certain data obtained from $http in more than one place while keeping it DRY.