0

I have a function (see below) that writes a message out onto the screen. Whenever you're actively viewing the page that it is running on, it prints out just fine; however, say you're watching a video in another tab and switch back to the tab that is writing out the function, the text comes out all jumble. e.g: "This is a message." generally would come out scrambled like "t isa hismg esseg."

The function in question:

params:

message: string

object: an HTML Object

function writeMessage(message,object){
    var i = 0;
    var interval = setInterval(function(){
        if(i < message.length){
            object.append(message.substr(i,1));
            i++;
        }else{
            clearInterval(interval);
        }
    }, 25);
}

Any idea as to why this happens?

  • That's strange. As an aside, the _return true;_ isn't doing anything except stop the _clearInterval()_ from executing (_setInterval()_ doesn't care what is returned by the function you pass it). – nnnnnn Nov 27 '13 at 01:18
  • 1
    This sounds like something that a mobile device would do to save power. I think my iPhone doesn't carry out interval events unless you're on the page. – Waleed Khan Nov 27 '13 at 01:19
  • @WaleedKhan Hmm, I'm not sure this is the case as it's most definitely on my desktop. I can confirm all intervals/settimeouts are running, it's just when I switch to the page after execution the written message is gibberish. – user3029571 Nov 27 '13 at 01:28
  • 1
    When you switch the page, the process running that page (in Chrome at least) loses priority. When you switch back to the page, it's going to try and catch up - I'm guessing at that point it has a bunch of setInterval function() executions it's going to execute in a somewhat arbitrary order so while i is being incremented sequentially, those functions aren't being evaluated in that same order. Which would explain why the message comes through, just jumbled. – Mike Pugh Nov 27 '13 at 01:32
  • @MikeP That sounds like a logical explanation. Any idea how you can prevent this from happening or implementing a "hotfix?" It's not a major issue, just a major annoyance. – user3029571 Nov 27 '13 at 01:48
  • This post might be relevant: http://stackoverflow.com/questions/6183463/when-using-setinterval-if-i-switch-tabs-in-chrome-and-go-back-the-slider-goes – linstantnoodles Nov 27 '13 at 02:04
  • @user3029571 - you could switch your logic to use the current time to calculate how much of the message to display. It looks like you want the system to draw a letter every 25 ms, store the start time instead of i and within your setInterval function you can evaluate the current time and change object to be equal to message.substr(0, x) where x is the number of characters determined by elapsed time / 25 ms, up to the point where x = message.length-1. It's a bit more complicated but it should survive user tabbing. – Mike Pugh Nov 27 '13 at 02:30

1 Answers1

2

I haven't tested that, but if what the comments say is true, you should be able to avoid that by manually chaining individual delayed operations. Instead of defining one interval, you should be able to call one timeout (setTimeout function), that appends the letter to the object and then calls itself recursively while passing the rest of the message to the recursive call.

In this case, if the device gives your asynchronous action no processor time, at least the subsequent actions won't be created and executed - because only the code in the first (now waiting) action could do that.

Alternatively you can use Reactive Extensions to generate an observable interval, upon which you can subscribe and update the object with your message. If you're not familiar with reactive programming, it might be a huge new topic for you, but I can certainly recommend it - if only just as a brain-teaser to see a different approach to programming.

Honza Brestan
  • 10,637
  • 2
  • 32
  • 43
  • +1 It has long been recommended to avoid `setInterval` and use recursive `setTimeout` instead. You'll avoid many race conditions this way, and I believe you'll avoid the problem you're posting about as well. – JAAulde Nov 27 '13 at 02:39