2015-04-15 2 views
2

На моей фабрике AjaxPromiseService.js я пытался включить механизм тайм-аута в вызовы с обещаниями (обычно $ http.get/post звонки в удаленные службы). То, как я сейчас делаю, - это создать гонку между событием $timeout и действительными обещаниями. Пример кода следующим образом (код из моего AjaxPromiseService.js завода в AngularJS): also available in this plnkrAngularJS: время ожидания вызова

var timeoutObj = {"isTimeout": true}; 

function timeoutPromise(deferredObj) { 
     $timeout(function() { 
     console.log("promise timeout"); 
     deferredObj.resolve(timeoutObj); 
     }, timeoutLimit); // timeoutLimit is in milisecond 
    } 

//promise calls (e.g. $http.get()) 
function getDummyData(milisec) { 
     var data = {"data" : "dummy data from ajax!"}; 
     var deferred = $q.defer(); 

     timeoutPromise(deferred); //start the race to see who resolves first 

     //use $timeout to mimick an AJAX call 
     $timeout(function() { 
     deferred.resolve(data); 
     $timeout.cancel(timeoutPromise(deferred)); //not working, how to cancel the race here? 
     }, milisec); // 

     return deferred.promise; 

    } //getDummyData 

Это кажется работает, если getDummyData() не будет решена в течение указанного срока, то timeoutPromise() вернет полезный флаг, так что я могу позволить вызовы AJAX неудачно изящно. И timeoutPromise(), и getDummyData() разрешат в конечном итоге в последовательном порядке, однако я бы хотел, чтобы отменитьtimeoutPromise(), если getDummyData() решено первым. Мне было интересно, как это сделать?

ответ

2

$http имеет параметр timeout, который раз из запроса, когда разрешенное обещание - это так, вы могли бы дать ему $timeout обещание:

getData: function(input, timeout){ 
    var timeoutPromise = timeout ? $timeout(function(){}, timeout) : null; 

    return $http({url: "/some/url", 
       timeout: timeoutPromise, 
       method: "GET" 
       }).then(function(response){ 
        var data = response.data; 
        // do something with data, if needed 
        return data; 
       }); 
} 

DEMO

+0

мне нужно вернуть prommise, не разрешенные данные. спасибо – TonyGW

+0

'return $ http(). then()' возвращает обещание ... Я не уверен, что вы просите иначе - обещание чего? –

+0

, поэтому вам не нужно обертывать $ q.defer() в $ http(), чтобы вернуть обещание? – TonyGW

1

Если вы используете $ http, есть намного более простой вариант. Используйте тайм-аут свойство $ HTTP объекта конфигурации и $ службы тайм-аута:

var requestTimeout = $timeout(function() {}, 4000); 
$http({ method:'GET', url:'...', timeout: requestTimeout}); 
requestTimeout.then(function() { 
    console.log ('request aborted - timed out!'); 
}); 

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

1

Согласно $http documentation, то timeout собственностью $ HTTP конфигурации принимает либо обещание, либо число в миллисекундах:

timeout - {number|Promise} - таймаут в миллисекундах, или обещание который должен прервать запрос при его разрешении.

Поэтому решение прост:

function getData() { 
    return $http.get(someUrl, {timeout: 3000}); // adjust the value to what you need 
} 
Смежные вопросы