I am currently developing something where both setInterval and setTimeout needs to be used. I am running setTimeout and dynamic delay is passed on to setTimeout.
While each element not being timed out from the above, I am running setInterval to print out the numbers.
The code is following
const data = [
{ "entry": "But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness." },
{ "entry": "No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful." },
{ "entry": "Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure." },
{ "entry": "This is a short one." },
{ "entry": "This is line two and it is long" },
{ "entry": "This is line two and it is long" },
{ "entry": "This is line three and it is also long" },
{ "entry": "This is line four and it is very very long" },
{ "entry": "This is line five and it is the longest line of all" },
{ "entry": "This is line six and it is longer than the previous line" },
{ "entry": "B" },
{ "entry": "Who built this country hand by hand, brick by brick. (Applause.) They all came here knowing that what makes somebody an American is not just blood or birth, but allegiance to our founding principles and the faith in the idea that anyone from anywhere can write the next great chapter of our story." }
];
//what is the string length of each
const stringLength = [];
//get each string Length
data.forEach(
(a, i) => {
stringLength.push(a.entry.length);
}
);
//container to custom define outer delay for each setTimeoutLoop
const outerDelay = [];
//predefined each inner delay
const innerDelayEach = 10;
//predefined delay
data.forEach(
(a, i, r) => {
(i === 0) ? outerDelay.push(0 * innerDelayEach): outerDelay.push(r[i - 1].entry.length * innerDelayEach);
}
);
//counter for outerLoop
let cntOuter = 0;
const elmnt = document.querySelectorAll('div');
const outerTerminator = elmnt.length - 1;
//console.log(elmnt);
function show() {
const select = elmnt[cntOuter]; //get the element based on current counter for outerLoop
//construct inner loop
//what happens till the element is not timed out
let cntInner = 0;
const inner = setInterval(
function() {
const text = select.textContent;
const innerTerminator = text.length - 1;
const val = text[cntInner];
console.log(cntOuter, cntInner, val);
cntInner++;
if (cntInner > innerTerminator) {
clearInterval(inner)
}
}, innerDelayEach
)
cntOuter++; //increment the outer counter
if (cntOuter > outerTerminator) return; // terminate outer loop when outer count > no. of divs
setTimeout(show, outerDelay[cntOuter])
};
show();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness.</div>
<div>No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful.</div>
<div>Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure.</div>
<div>This is a short one.</div>
<div>This is line two and it is long</div>
<div>This is line two and it is long</div>
<div>This is line three and it is also long</div>
<div>This is line four and it is very very long</div>
<div>This is line five and it is the longest line of all</div>
<div>This is line six and it is longer than the previous line</div>
<div>B</div>
<div>Who built this country hand by hand, brick by brick. (Applause.) They all came here knowing that what makes somebody an American is not just blood or birth, but allegiance to our founding principles and the faith in the idea that anyone from anywhere can write the next great chapter of our story.</div>
</body>
<script type="text/javascript"></script>
</html>
With the above, I expect the browser to make the callbacks from setTimeout at the delay defined and while each element is not timed out, I expect to see the setinterval printing out the character values without any overlap.
Yet, I see this overlap which I don't expect at all. I expect the cntOuter=1 to execute till cntInner=263. But it goes to cntOuter=2 while cntInner=240`.
Something is obviously wrong which is causing this overlap. But I don't understand what is triggering that.
