我有一个获取报告的服务:
ReportsResource.getActiveUsers()
。这使用$http
然后返回一个promise。
然后我就这样使用它:
var request = ReportsResource.getActiveUsers();
request.then(populateActiveUsersTable, handleError);
但是,问题是,在后端获取活动用户报告的请求可能需要几秒钟到30多分钟。
如果您发出请求并且没有可用的缓存报告,它会生成报告,然后请求会等待该请求的数据(同样,可能是2秒或30分钟)。
< / LI>如果您发出请求并且当前正在生成报告,则会立即返回响应,告知您报告尚未就绪。此时,您可以继续轮询以查看报告是否已准备就绪。
如果报告已准备好(缓存),则会立即返回报告数据的响应。
我需要的是将请求包装在等待最多10秒的超时中,然后在响应时间超过10秒后中止,并开始轮询服务器以询问报告是否已准备就绪。但是如果请求在10秒内解决,它应该取消超时并正常执行promise链。
不确定如何处理这个。
答案 0 :(得分:0)
根据情况,我认为最好使用WebSocket而不是timeout
功能。使用WebSocket,您只需要注册每次从服务器发送更新/更改时运行所需的功能。 websocket不需要保持轮询,而是需要更少的资源和更高的效率。但它需要在后端做一些工作。
实现延迟了不同的后端语言。您可能需要与后端人员(或您自己)交谈。希望这可以给你一些想法。
===编辑===
如果您想使用timeout
或interval
等服务,请使用以下代码:
//inside your controller
var pollingPromise = $q.defer(); //used to controll the fired $http request
var pollingActiveUsers = function() {
ReportsResource.getActiveUsers(pollingPromise).then( function(data){
//stop polling
$interval.cancel(pollingProcess);
//set to the controller's scope
$scope.activeUsers = data;
//populate the activeUsersTable
populateActiveUsersTable();
});
};
//init the first request
pollingActiveUsers();
//polling for every 10secs
var pollingProcess = $interval( function() {
//resolve the previous polling request which mean cancel the previous $http request if it waits longer than 10 secs
pollingPromise.resolve();
//start another polling, a new pollingPromise is required
pollingPromise = $q.defer();
pollingActiveUsers();
}, 10000);
//In your service ReportsResource
//you have to make another change function getActiveUsers() to make this work, you have to pass the pollingPromise to the $http method, so you can cancel the $http request:
var function getActiveUsers = function(promiseObj) {
return $http.get('someUrl', { timeout: promiseObj });
};
很少有人担心:
pollingPromise
是我们需要的。更多信息:cancel unresolved promise $interval
解决此问题,$interval.cancel()
函数将停止此间隔。在您的应用中应用时,可能需要更改代码。
答案 1 :(得分:0)
将$q {{3}}与$timeout
一起使用。使用$q.defer()
创建延迟,使用超时创建请求,并在then处理程序中转发结果以解决延迟。如果请求超时,则开始轮询。立即退还延期的承诺。
var d = $q.defer() // defered for the final result
function poll() {
$http({...}).then( //poll request
function(res) {
if (ready(res))
d.resolve(res)
else {
$timeout(poll, 10000)
}
},
function(err) {
d.reject(err)
})
}
$http({ timeout: 10000, ... }).then(
function(res) {
d.resolve(res)
}, // return result directly
function(err) { // error or timeout
if (realError(err)) // check if real error
d.reject(err)
else { //timeout
$timeout(poll, 10000)
}
})
return d.promise
您可以重复使用返回的promise,经常调用then
来等待或获取缓存的结果。