I'm working on an application with a large amount of lazy data loading. I would like to prioritize http requests based on 'priority' param.
This is the concept of using it.
$http.get(url, {params: query, priority: 1})
I was thinking of using $http interceptors. Something like that:
angular.module('myModule')
.factory('httpPriorityInterceptor', function ($interval, $q) {
var requestStack = [];
return {
request: function (config) {
config.priority = config.priority || 3;
requestStack.push(config);
requestStack.sort(sortByPriority);
if (isFirstToGo(item)) return requestStack.pop();
deferred = $q.defer();
var intervalPromise = $interval(function(){
if (isFirstToGo(item)) {
deferred.resolve(requestStack.pop());
$interval.cancel(intervalPromise);
};
}, 100);
return deferred.promise;
}
};
});
But I can't return promise here. Any ideas?
Try to wrap your timeout
Seems like it's getting lost on $interval. aswell your deferred was instanced globaly set a
var
before.This was not the right solution. You can achieve this by writing your own service to prioritize your api calls queue before calling http get .
This will not work for the following use case Angular Http Priority
You can do this by making use of
$http
's timeout property, and use bothrequest
andresponseError
callbacks to save and execute each$http
requests respectively.Steps:
Lazily inject the
$http
service within therequest
callback process, this will be the only way to get the$http
service because injecting it in the factory's function causes circular dependency.Determine if the configuration passed in the
request
callback has been processed. If it has not been processed then add the configuration in the request stack and sort it by priority. Add a resolved promise in the timeout property of the configuration object, to cancel the current$http
request. Finally return the configuration object.Once the
$http
request has been cancelled, catch it in theresponseError
callback. If there are items in the request stack, pop the first item(config) and invoke it using the lazy loaded$http
service. Lastly return a rejected promise using the rejection parameter provided by the callback.DEMO
To make sure that each request has been invoked in the right order, you can check the logs in the console tab or the requests in the network tab.
Update:
If you want your requests invoked in order (when the first request must finish before the next request invokes) then you can tweak my solution in the
responseError
callback to something like this:DEMO
UPDATE 06/16/2019
As mentioned in the comments, the promise returned by prioritized requests do not return the expected promise resolution or rejection. I have updated the interceptor to accommodate such scenario by:
responseError
interceptor for sake keeping the resolution or rejection of the request.DEMO