Pregunta

I have an AngularJS application which perform - 1 request to fetch the main user profile, that contains references to the user friends, - and then 1 request per friend to retrieve the friend profile.

When we click on a friend's profile, we load this profile as the main profile.

I am in the RDF / semantic web world, so I can't model these interactions differently, this is not the point of the question.

This is an early version of the application I'm trying to build, that can help you understand what's my problem: http://sebastien.lorber.free.fr/addressbook/app/


The code looks like:

$scope.currentProfileUri = 'http://bblfish.net/people/henry/card#me';

$scope.$watch('currentProfileUri', function() {
  console.debug("Change current profile uri called with " + $scope.currentProfileUri);
  loadFullProfile($scope.currentProfileUri);
})

// called when we click on a user's friend
$scope.changeCurrentProfileUri = function changeCurrentProfileUri(uri) {
  $scope.currentProfileUri = uri;
}

function loadFullProfile(subject) {
  $scope.personPg = undefined;
  // we don't want to capture the scope variable in the closure because there may be concurrency issues is multiple calls to loadFullProfile are done
  var friendsPgArray = [];
  $scope.friendPgs = friendsPgArray;
  fetchPerson(subject).then(function(personPg) {
    $scope.personPg = personPg
    fetchFriends(personPg,function onFriendFound(relationshipPg) {
      friendsPgArray.push(relationshipPg);
    });
  },function(error) {
    console.error("Can't retrieve full profile at "+uri+" because of: "+error);
  });
}

So the friends are appended to the UI as they come, when the http response is available in the promise.

The problem is that the function changeCurrentProfileUri can be called multiple times, and it is possible that it is called by while there are still pending requests to load the current users's friends.

What I'd like to know is if it's possible, on changeCurrentProfileUri call, to cancel the previous http requests that are still pending? Because I don't need them anymore since I'm trying to load another user profile. These pending requests will fill an instance of friendsPgArray that is not in the scope anymore and won't be put in the scope, so it is just useless.


Using Java Futures, or frameworks like RxScala or RxJava, I've seen there's generally some kind of "cancel" or "unsubscribe" method which permits to de-register interest for a future result. Is it possible to do such a thing with Javascript? and with AngularJS?

¿Fue útil?

Solución

Yes, it is! Please, see this section of angular $http service docs. Note timeout field in config object. It does, I think, exactly what you need. You may resolve this pormise, then request will be marked as cancelled and on error handler will be called. In error handler you may filter out this cases by there http status code - it will be equal to 0.

Here is fiddle demonstrating this

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top