Last active
February 6, 2023 14:57
-
-
Save twmbx/2321921670c7e95f6fad164fbdf3170e to your computer and use it in GitHub Desktop.
Polling in JS with an async ajax call that returns a promise ( modified from: https://davidwalsh.name/javascript-polling )
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// The polling function | |
function poll(fn, timeout, interval) { | |
var endTime = Number(new Date()) + (timeout || 2000); | |
interval = interval || 100; | |
var checkCondition = function(resolve, reject) { | |
var ajax = fn(); | |
// dive into the ajax promise | |
ajax.then( function(response){ | |
// If the condition is met, we're done! | |
if(response.data.var == true) { | |
resolve(response.data.var); | |
} | |
// If the condition isn't met but the timeout hasn't elapsed, go again | |
else if (Number(new Date()) < endTime) { | |
setTimeout(checkCondition, interval, resolve, reject); | |
} | |
// Didn't match and too much time, reject! | |
else { | |
reject(new Error('timed out for ' + fn + ': ' + arguments)); | |
} | |
}); | |
}; | |
return new Promise(checkCondition); | |
} | |
// Usage: get something via ajax | |
poll(function() { | |
return axios.get('something.json'); | |
}, 2000, 150).then(function() { | |
// Polling done, now do something else! | |
}).catch(function() { | |
// Polling timed out, handle the error! | |
}); |
we can use Promise.all for multiple polls, follow the below example
Promise.all([poll(function() { return axios.get('something.json'); }, 2000, 150),poll(function() { return axios.get('something2.json'); }, 2000, 150),poll(function() { return axios.get('something3.json'); }, 2000, 150)])
i have not tried this but this should work
I needed something similar, but didn't need the timeout. Leaving this here for others:
const continuousPromise = (promiseFactory, interval) => {
const execute = () => promiseFactory().finally(waitAndExecute);
const waitAndExecute = () => window.setTimeout(execute, interval);
execute();
}
//Usage
continuousPromise(() => axios.get("something.json"), 150);
nice usage of promise for polling
Here is a version that i adjusted to get working for me , also this shows how axios resolves for data also .
function poll(fn, timeout, interval) {
const endTime = Number(new Date()) + (timeout || 2000);
interval = interval || 100;
const checkCondition = (resolve, reject) => {
let ajax = fn();
ajax.then(response => {
if (response.statusText === "OK") {
resolve(response.data);
} else if (Number(new Date()) < endTime) {
setTimeout(checkCondition, interval, resolve, reject);
} else {
reject(new Error('time out for ' + fn + ' : ' + arguments));
}
});
};
return new Promise(checkCondition);
}
poll(() => {
return axios.get("https:some_url", {
params: {
getParam1: 1234567
}
});
}, 200, 150).then(res => {
console.log(res); // here is where you use the result to call a function blah blah
}).catch(() => console.log('failed to get data'));
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
How would you have multiple polls on the same page?