0

I've seen many others ask questions to do with this but none of the answers actually work and don't apply to my situation.

I just simply want to implement a delay within my for each loop of variable time lengths. These variable time lengths come from the array I am looping through when reading the json file. To give further context, the aim is to highlight each word in a sentence for a variable amount of time - each word has timing in milliseconds associated with it from the json file.

My assumption is that the solution is something to do with setTimeout but every time I try that it waits initially but then skips all the rest.

My code right now:

  $("[id^='timing_check']").click(function() {
    sn = $(this).attr('name');
    ayahnum = $(this).attr('data-id');

    $.getJSON("/static/json/mishary.json", function(result) {
      $.each(result, function(i, v) {
        if (v.ayah == ayahnum && v.surah == sn) {
          var x = v.segments;
          var i = 1;

          x.forEach(function(item) {
            time_sleep = item[3];
            wordref = sn + ':' + ayahnum + ':' + i;
            i++;

            setTimeout(function() {
              $("[name='" + wordref + "']").css('color', 'red');
            }, time_sleep);
          });
        }
      });
    });
  });
});             

This doesn't work at all. Not even close. Please offer some guidance

5
  • 2
    For us to diagnose any issues we will need to see the HTML as well as an example of the JSON response Commented May 29, 2018 at 14:42
  • Also... should all words being colored at once for a random amount of time, or should the next word receive color after the last one lost it - because in the later case a forEach wouldn't be the right choice... also if the text is very long it's possible you don't see anything because your forEach is blocking the thread, as the Jquery-Selection can be very slow... i ran in a similar problem wenn doing validation of a lot of rows... Javascript ( without web-workers) single threaded and setTimeout moves the payload to perform at the last position of the active thread... Commented May 29, 2018 at 14:59
  • So when your running methode doesn't finish you don't get to see anything becouse the timeouts aren't executed... At least as far as i know... Take it with a grain of salt... Commented May 29, 2018 at 15:00
  • here: stackoverflow.com/questions/750486/… stackoverflow.com/questions/5226285/… Commented May 31, 2018 at 13:45
  • Possible duplicate of JavaScript closure inside loops – simple practical example Commented May 31, 2018 at 13:46

1 Answer 1

1

I think the problem is as follow, let's suppose this code:

array1 = [1000, 2000, 1000, 4000, 10000];
array1.forEach(function(item) { //all actions start at 0

        setTimeout(function() {
            console.log("some action of item "+item);
        }, item);

    }

);

All setTimeout function are calculated from 0+item time, so the times 1000 and 1000 are going to be executed at the same time. Maybe you want to account the time like item[i1]+item[i2], then you have to sum all the times spent in each iteration. The code in that way would be something like:

array1 = [1000, 2000, 1000, 4000, 10000];

var abs = 0;//beginning 

array1.forEach(function(item) {

        if(!abs){
            abs = item;
        }else{
            abs += item;//sum time spent
        }
        console.log("set "+abs+" to setTimeout");

        setTimeout(function() {
            console.log("some action of item "+item);
        }, +abs);

    }

);

In this example, the 2th 1000 will be calculated after 1000 and 2000 that is 4000 ms after the loop is fired.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.