2015-04-15 148 views
2

在我的AjaxPromiseService.js工廠中,我一直試圖將超時機制納入承諾調用(通常爲$ http.get/post調用遠程服務)。我目前的做法是在$timeout事件和實際承諾呼叫之間建立一個競賽。示例代碼如下(以AngularJS代碼從我AjaxPromiseService.js廠):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

$httptimeout參數,超時請求時承諾解決 - 所以,你可以給它一個$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

因此,您不需要在$ http()中包裝$ q.defer()來返回承諾? – 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 
}