2015-04-15 88 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 
}