Overlapping problem with setInterval

I am currently working on a project that requires the use of both setInterval and setTimeout. I am using setTimeout with dynamic delays passed to it.

While elements are not timed out, I have implemented setInterval to print out numbers.

Here is the code snippet:

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." }
];

// Calculate string length for each entry
const stringLength = [];

data.forEach(
    (a, i) => {
        stringLength.push(a.entry.length);
    }
);

// Container to define outer delay for each setTimeout loop
const outerDelay = [];

// Predefine inner delay
const innerDelayEach = 10;

data.forEach(
    (a, i, r) => {
        (i === 0) ? outerDelay.push(0 * innerDelayEach): outerDelay.push(r[i - 1].entry.length * innerDelayEach);

    }
);

let cntOuter = 0;

const elmnt = document.querySelectorAll('div');
const outerTerminator = elmnt.length - 1;

function show() {

    const select = elmnt[cntOuter];   
  
    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++; 
    if (cntOuter > outerTerminator) return; 
    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>...</div>
    ...
  </body>
  <script type="text/javascript"></script>
</html>

With the above setup, I expect the browser to execute the callbacks from setTimeout at the specified delays, and I expect to see the characters printed by setInterval without any overlap as long as each element is not timed out.

However, I am experiencing unexpected overlap in the output. Instead of cntOuter=1 executing till cntInner=263, it goes to cntOuter=2 while cntInner=240.

https://i.stack.imgur.com/rWKtR.png

There seems to be an issue causing this overlap, but I'm unable to identify the trigger.

Answer №1

Understanding the logic of your code can be a bit challenging. One thing that stands out is that the inner loop runs every outerTerminator milliseconds, seemingly influenced by the number of entries you have. It would make more sense for the inner loop to pause for innerDelayEach milliseconds instead of outerTerminator milliseconds.

An alternative approach that enhances readability involves utilizing async/await with two nested loops and delays:

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." }
];

function sleep(delay) {
  return new Promise((resolve, reject) => setTimeout(resolve, delay));
}

async function type(data, delay) {
  const container = document.querySelector('#container');
  for (const item of data) {
    const div = document.createElement('div');
    container.appendChild(div);
    for (const c of [...item.entry]) {
      div.textContent += c;
      await sleep(delay);
    }
  }
}

type(data, 10);
<div id="container"></div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

AngularJS: Unable to preserve the data

I'm currently working on an issue with saving updated functions using angularJS. I've managed to edit the data and update it on the database side, but the changes aren't reflecting on the frontend side unless I logout and login again. I need ...

Retrieving information from CRM online utilizing the Web API

Recently, I developed a webpage to serve as a survey for end users to provide feedback on the helpdesk technician's performance in resolving tickets. The webpage was constructed using HTML, CSS, JS, and PHP. Currently, the page requires access to two ...

Obtaining a specific item from a group using AngularJS. Utilizing a declarative method

Consider a scenario where you need to apply a CSS rule to a specific element within a collection that needs to be selected. <div ng-repeat="fragments" ng-click="makeSelected()"></div> $scope.fragments = [ {id: 6379, someProperty: "someValu ...

Encountering issues when using react-leaflet in a React project with webpack integration

I've been attempting to import react-leaflet into my project without actually rendering any maps, but I keep getting this error message. TypeError: Object(...) is not a function I am certain that the issue stems from the import statement, as indica ...

Generate star icons dynamically within a div using C# and MSSQL data to determine the number of stars

Upon retrieving a rating (which can be more than 5) from the database, I aim to dynamically generate glyphicon stars based on the received value when the page loads. The code snippet below demonstrates how the value is retrieved: int rating_count = DBinte ...

Leveraging RXJS for efficient data retrieval in nodejs

When dealing with sending a bulk of data and moving on to the next one upon completion, it can be quite challenging. Take for instance this function: async function test() { await sample.sampleStructure() await sample.sampleDataAdd() await sample.sa ...

The failure of a unit test involving Jest and try-catch

I am facing an issue with creating unit tests using jest. exportMyData.js const createJobTrasferSetArray = async () => { const data = exportData(); const jobTransferSet = []; try { data.forEach((element) => { const JobPathArray = el ...

Issues are arising with Jquery Scripts when running through Selenium in IE 9, resulting in the error message SCRIPT5009: '$' is undefined. However, these scripts are functioning correctly when executed directly in the web browser

While using Selenium, the code below is causing issues as it is not functioning properly. An error SCRIPT5009: '$' is undefined is being thrown in IE 9. However, if the code is executed in a web browser console after removing the "\" sign, i ...

When utilizing Reactjs, accessing an element by its id becomes challenging when the element is nested within a map() function

Currently, I am encountering an issue related to reactjs. In my scenario, I have a requirement to compare the height of the screen with a specific div to determine its maximum width. The challenge lies in the fact that the particular div I need to analyz ...

Smooth-scroll plugin does not activate active state (due to JS modification)

I'm currently facing an issue with a script that handles smooth scrolling and the active state on my main navigation. The plugin in question can be found at: It's important to note that the navigation bar is fixed and therefore has no height. T ...

Exploring the proper method for closing connections in Node JS and the pg module

I'm experiencing frustration with the node pg module as I keep encountering a 'too many clients already' error. For instance, in my app.js file, I handle various routes where I query data from postgres. Here's a snippet of how app.js i ...

Explaining the jQuery $.post method

After a thorough search, I finally discovered the importance of adding return false; at the end of my JQuery code for posting data. Without it, my code wasn't functioning as expected. As a beginner in JQuery, I would appreciate some insights into the ...

The 'substr' property is not found in the type 'string | string[]'

Recently, I had a JavaScript code that was working fine. Now, I'm in the process of converting it to TypeScript. var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress; if (ip.substr(0, 7) == "::ffff ...

Adjusting the size of the iframe to match the dimensions of the window

Is there a way to make the iframe automatically fill up the entire space? For example, only opens the iframe up to half of the window in Mozilla Firefox and IE6. How can I ensure that it takes the maximum size of the screen? Are there any CSS or JavaScr ...

Step-by-Step Guide for Attaching Table Legs

I believe that the four legs should be an integral part of the table, rather than just added on like an afterthought. What would be the best way to create new instances of legs and attach them in a way that makes the back legs look slightly smaller than t ...

Inspecting a substring of an element dynamically added in VueJs

When I click a button in my form, it adds a new line. The challenge is making sure that each new line evaluates independently and correctly. In this case, the task involves checking the first 2 digits of a barcode against a dataset to determine a match or ...

Reading properties of undefined in React is not possible. The log method only functions on objects

I'm currently facing an issue while developing a weather website using the weatherapi. When I try to access properties deeper than the initial object of location, like the city name, it throws an error saying "cannot read properties of undefined." Int ...

Using Chrome.downloads.download within a Chrome application

My app is running into an issue where Chrome is giving me the error message that chrome.downloads is undefined. In my attempt to download an image, here is a simple example provided... Here is the manifest: { "manifest_version": 2, "name": "Download ...

Is there a way to verify the presence of a particular value in a list?

I need to validate the content of all li tags within a ul list. If any list item contains the text "None," then I want to append specific text to a div. If no li tag includes "None," then different text should be added to the div. Upon checking my code, I ...

Error message: "Attempting to assign a value to the 'size' property of an undefined object, despite the fact that

I recently started delving into NodeJS development and have configured Visual Studio Code for JavaScript development in node applications. During a Pluralsight lecture on Objects, the instructor demonstrated creating two scripts, dice.js and program.js, a ...