setTimeout function timesout not the given time

Hi,

In a Function Node I use the "setTimeout" function twice
The first timeout takes exactly 2 seconds (2000 ms)
The last timeout takes exactly 5 seconds, however I have have set it at 7 seconds (7000 ms)
When I set the timeout to 9 seconds it takes the 7 seconds I wanted it to timeout

Why is this difference?

var msgVolumeSet = {
  payload: {
    type: "VOLUME",
    volume: 70
  }
};

var msgMedia = {
  payload: {
    type: "MEDIA",
    media: {
      url: "http://192.168.1.51:1880/wekker",
      contentType: "audio/mp3",
      streamType: "BUFFERED"
    }
  }
};

var msgVolumeBack = {
  payload: {
    type: "VOLUME",
    volume: 45
  }
};

if (msg.payload.idx == '253') {
    if (msg.payload.nvalue == '1') {
      
      node.send(msgVolumeSet);
      
      setTimeout(function(){
        node.send(msgMedia);
      }, 2000);
      
      setTimeout(function(){
        node.send(msgVolumeBack);
      }, 7000);
    }
}

The first message will be emitted immediately, the second one―2 seconds later, the third one―5 seconds after the second (i.e. 7 seconds after the first one).

What was your expectation?

Another way of thinking about it is that JS is running through the script a full speed. When it gets to the statements setting up the timeouts, it doesn't stop, the timeout functions are async, they happen out of band.

You could change the order of the setTimeout functions and the same thing would happen because they are not dependent on each other. In other words, they effectively run in parallel.

The other thing to note is that because JavaScript is not a real-time processing language, you cannot rely on the exact timing. Depending on the complexity of the code it could be slightly out and typically will be by at least a few milliseconds. Not normally an issue but may catch you out occasionally. Especially if you write some code that contains a long-running synchronous task that "blocks" the processing loop that is inherent in the way that JavaScript works. Then you could end up with the timeout functions running several seconds out of step in extreme cases.

Yeah your right...I thought the second timeout would start after the first was finished.
Thanx!

Thanx for the info, my function is not complex, I only have to send 3 messages in a specific format to a Google Home Mini in a sequence but they can't be send at the same time, so I tried the setTimeout function.

No, it isn't complex and clearly doesn't need to be, I was just trying to offer some alterative ways of thinking about how JS is processing your timeouts & perhaps more importantly why it works that way rather than some other way.

What other way would you suggest then?...I tried it with a delay node and a queue node but in both cases I couldn't figure out how to achieve the same result.
I just started with node-red, and trying to find my way

I would say it is fine as it is. But if you really want to make the second timeout dependent on the first, all you need to do is to define it INSIDE the first timeout function.

Ah OK, didn't know that.
Well one important thing with the castv2 node (where i use this function for) that each of the 3 messages (which are commands to contol the cast) has to finish first before the other starts otherwise it is overruled by the next command in line.
So the timeout is based on the duration of the command.

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.