【发布时间】:2018-01-11 17:26:06
【问题描述】:
我希望轮询端点不快于每秒一次,并且不慢于轮询端点所需的时间。决不能有超过一个未完成的请求。
我想要一种响应式编程方式来至少每秒轮询一次端点,但如果端点花费的时间超过 1 秒,则下一个请求会立即触发。
在下面的弹珠图中,第 2 次和第 3 次请求花费的时间超过 1 秒,但第 4 次和第 5 次请求完成得更快。下一个请求在 1 秒边界触发,或者在从最后一个未完成的请求中获取数据后立即触发。
s---s---s---s---s---s---| # 1 second interval observable
r---r----r--------r-r---| # endpoint begin polling events
-d-------d--------dd-d--| # endpoint data response events
我正在尝试在大理石图中正确使用术语,所以我 假设端点请求的开始应该是 大理石我标记为“r”,大理石事件我标记为“d”有端点数据。
这是我用纯 js 完成此操作所需的代码量;但是,正如我上面所要求的那样,后续请求不会在获得后立即触发。
var poll;
var previousData;
var isPolling = false;
var dashboardUrl = 'gui/metrics/dashboard';
var intervalMs = updateServiceConfig.getIntervalInMilliSecondForCharts();
return {
startInterval: startInterval,
stopInterval: stopInterval
};
function startInterval() {
stopInterval();
tryPolling(); // immediately hit the dashboard
// attempt polling at the interval
poll = $interval(tryPolling, intervalMs);
}
/**
* attempt polling as long as there is no in-flight request
* once the in-flight request completes or fails, allow the next request to be processed
*/
function tryPolling() {
if (!isPolling) {
isPolling = true;
getDashboard()
// if the dashboard either returns successful or fails, reset the polling boolean
.then(resetPolling, resetPolling);
}
}
/** there's no longer an in-flight request, so reset the polling boolean */
function resetPolling() {
isPolling = false;
}
function stopInterval() {
if (poll) {
$interval.cancel(poll);
poll = undefined;
}
}
function getDashboard() {
return restfulService.get(dashboardUrl)
.then(updateDashboard);
}
function updateDashboard(data) {
if (!utils.deepEqual(data, previousData)) {
previousData = angular.copy(data);
$rootScope.$broadcast('$dashboardLoaded', data);
}
}
【问题讨论】:
标签: rxjs observable