Skip to content

Instantly share code, notes, and snippets.

@motss
Last active March 7, 2017 08:38
Show Gist options
  • Save motss/5b0c1988bb426b59f74cc590347a3fae to your computer and use it in GitHub Desktop.
Save motss/5b0c1988bb426b59f74cc590347a3fae to your computer and use it in GitHub Desktop.
Long Polling with interval and max duration with ES6+
/**
* Long polling happens in each successive `interval` and the long polling only allows to continue for `maxDuration`.
* `maxDuration` determines the time at which enough useful information has been gathered over the intervals,
* after all, things that too slow possess lesser significance by assumptions else they need to be improved
* if they are really important as no important/ high priority should load this slow.
* See [RAIL model](https://developers.google.com/web/fundamentals/performance/rail) for more info.
*
* Required parameters:
* 1. interval - how long the subsequent polling starts.
* 2. max duration - time reached to send out whatever has been gathered at that point.
*/
let nPoll = 0;
let requestStarts = 0;
const responseComplete = 20E3;
const interval = 2E3;
const maxDuration = 10E3;
class LongPolling {
static init(fn, condition, interval, maximumInterval) {
let duration = 0;
const cachedInterval = typeof interval === 'number' ? interval : 2E3;
return new Promise((resolve, reject) => {
const check = () => {
Promise.resolve()
.then(fn)
.then(condition)
.then((val) => {
if (typeof val !== 'boolean') {
throw new TypeError('Expected condition to return a boolean');
}
if (val === true || duration >= maximumInterval) {
resolve();
} else {
setTimeout(check, cachedInterval);
duration += cachedInterval;
}
})
.catch(reject);
};
check();
});
}
}
poll = LongPolling.init;
let completed = {};
(() => {
window.setTimeout(() => {
const requestEnds = window.performance.now();
console.info(`completed at ${+new Date()} after ${(requestEnds - requestStarts) / 1000}s\n`);
completed = Object.assign({}, completed, {
status: 200,
message: 'completed',
});
}, responseComplete);
})();
poll(
async () => {
nPoll++;
if (completed.status === 200) return completed;
return await Promise.resolve().then(() => {
if (requestStarts < 1) requestStarts = window.performance.now();
console.info(`${nPoll} - still in progress... ${+new Date()}\n`);
completed = Object.assign({}, completed, { status: 206, message: 'in-progress' });
return completed
});
},
(data) => {
console.log('condition: ', data, data.status === 200);
return data.status === 200;
},
interval,
maxDuration
)
.then(() => {
console.log('poll res:', completed);
})
.catch(err => {
console.error('poll error:', err);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment