Reputation: 333
I have a function called ajaxCall()
which simple does the call on a server and returns a value from a feed.
What I wanted to do is to save the value from feed to firstInterval
variable, wait 10 seconds, make the call again and save the value to secondInterval
variable. And then animate the increasing of these numbers on the webpage. This is what we have so far:
setInterval(function(){
getAmounts()
}, 11000);
function getAmounts(){
firstInterval = ajaxCall();
setTimeout(() => {
secondInterval = ajaxCall();
animateValue('#bronze-price p', firstInterval, secondInterval, 10000)
}, 10000);
};
function animateValue(id, start, end, duration) {
start = parseInt(start);
end = parseInt(end);
var range = end - start;
var current = start;
var increment = end > start? 1 : -1;
var stepTime = Math.abs(Math.floor(duration / range));
var obj = document.querySelector(id);
var timer = setInterval(function() {
current += increment;
obj.innerHTML = current;
if (current == end) {
clearInterval(timer);
}
}, stepTime);
}
So the idea is to have a function which gets first interval, after 10 seconds it grabs the second interval and calls the animation. This all is wrapped into setInterval function so I could change the number smoothly repeatedly.
However I am pretty sure that thats not a very clean solution since its setInterval
in setTimeout
and this all is wrapped in another setInterval
function. I am also getting this kind of warnings in the console with both functions:
[Violation] 'setInterval' handler took ms
What would be the best approach to follow up on this idea but optimize the code?
Upvotes: 1
Views: 78
Reputation: 54649
I think Promises
and requestAnimationFrame
makes this a lot easier to handle while also getting rid of setTimeout/setInterval
. An example would be:
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random#Getting_a_random_integer_between_two_values_inclusive
function getRandomIntInclusive(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// fake api endpoint
const ajaxCall = () => new Promise(resolve => {
setTimeout(resolve, 400, 1000 + getRandomIntInclusive(0, 1000));
});
// simple animation helper using requestAnimationFrame
const animate = (from, to, duration, cb) => {
const start = performance.now();
return new Promise(resolve => {
requestAnimationFrame(function loop() {
const f = (performance.now() - start) / duration;
cb(from + Math.round(f * (to - from)));
f < 1.0
? requestAnimationFrame(loop)
: resolve();
});
});
};
// main
(async (interval) => {
// where to output
const dst = document.querySelector('#out');
// initial value
let prev = 0;
// wait for next value of ajaxCall
while (true) {
const next = await ajaxCall();
console.log(`animating: ${prev} -> ${next}`);
// animate from `prev` to `next`
await animate(prev, next, interval, current => {
dst.innerHTML = current;
});
prev = next;
}
})(10000);
<div id="out"></div>
Upvotes: 1