LINUX.ORG.RU

Как заставить $http.then вызваться дважды?

 


0

1
angular
.module('app', ['ngStorage'])
.config(['$httpProvider', function ($httpProvider) {
    $httpProvider.interceptors.push('TestInterceptor');
}])
.factory('TestInterceptor', ['$q', '$injector', '$localStorage', function ($q, $injector, $localStorage) {
    return {
    	request: request,
    	response: response,
    	responseError: responseError
    };

    function request(config) {
    	console.log('request');
    	config.test = !config.test;
    	if (config.test) {
    		config.timeout = 1;
    	}  else {
			config.timeout = 10000;
    	}
    	return config;

    }
    function response(resp) {
    	console.log('response');
    	console.log(resp);
    	if (resp.config.method == 'GET' ) {
    		if (!resp.config.cached) {
    			var restCache = $localStorage.cache;
	    		if (restCache == null) {
	    			restCache = {};
	    		}
	    		resp.cached = true;
    			restCache[resp.config.url] = angular.toJson(resp);
    			$localStorage.cache = restCache;
    			
    		}
    		
    	} 
    	return $q.resolve(resp);
    }
    
    function responseError(rej) {
    	console.log(' responseError(rej) {');
    	console.log(rej);
    	var defer = $q.defer();
    	var config = rej.config;
    	if (config.test) {
    			function success(response) {
					defer.resolve(response);
    			}
    			function errorCallback(reject) {
    				defer.reject(reject);
    			}
    			$http = $injector.get('$http');
    			$http(rej.config).then(success, errorCallback);
		}
    	if (config.method == 'GET' && (rej.status == 408 || rej.status <= 0) && config.test) {
			var restCache = $localStorage.cache;
			if (restCache != null && restCache[rej.config.url] != null ) {
				return $q.resolve(angular.fromJson(restCache[rej.config.url]));
			}
    	}
    	return $q.reject(rej);
    }
}])
.run(['$http', function ($http) {
	$http.get('http://example.com/service/').then(function (res) {
		console.log('res');
		console.log(res);
	});
}]);

Возможно ли дернуть then дважды из interceptor'а?


Ответ на: комментарий от znenyegvkby

ну смысл такой: есть кэш, берем сначала данные из кэша отдаем в контроллер, параллельно делаем запрос на сервер, и если удалось обновляем кэш и отдаем новые данные в контроллер.

Смысл чтобы не ждать пока таймаут пройдет если данные какие то уже есть (пусть и устаревшие)

kote ()
Последнее исправление: kote (всего исправлений: 2)
Ответ на: комментарий от kote

.then — thenable, оно гарантированно исполняется 1 раз. Ты не скормишь 2 результата контроллеру, если он делает 1 вызов.

Ты можешь вернуть promise, который ждёт ответа от сервера и, в зависимости от результата, возвращает либо его, либо кэш.

x3al ★★★★★ ()
Ответ на: комментарий от x3al

Точнее, если ОЧЕНь хочется — скормишь, но это ломает спецификацию A+ promise и потенциально ломает вообще всё. Перепиши контроллер (а лучше — сервис/фабрику сделай).

x3al ★★★★★ ()
Последнее исправление: x3al (всего исправлений: 1)
Ответ на: комментарий от x3al

я правильно понимаю понимаю, что единственный более менее нормальный способ реализовать выше описанную задачу - это писать свою обертку над ngResource, которая будет принимать callback без всяких промисов и дважды его тупо дергать?

kote ()

Promise.resolve? Он вернет промис, которому уже и дашь then
ну типа:


.then((res) => {
  result = someactionsoverres(res);
  return result ? Promise.resolve(res) : Promise.reject(res);
}).then((res) => {
  otheractionsoverres(res);
});

mystery ★★ ()
Ответ на: комментарий от mystery
$http.get('http://example.com/service/')
.then(function (res) {
		result = getCache(...);
         ...
})
.then(function () {
  ...
});

если подразумевается что-то типа этого, то не пойдет:

1) оно не выдаст результат до таймаута

2) оно не перезатрет результат из кэша после получения данных с сервера.

Тут смысл в безотказности работы мобильного приложения на кордове. т.е вне зависимости от наличия интернета приложение должно работать и не тормозить, и если таки данные удалось получить то уже обновлять данные на странице, а не ждать по 10 сек пока до таймаут пройдет и только потом отдавать кэш, при том что данные там уже есть.

kote ()
Последнее исправление: kote (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.