Stop execution of a function node when calling it again

Hello, I am trying to create a custom node based on the function node, as a parameter two groups of initial RGBW and final RGBW color are passed, in addition to two values ​​(time and cycles).

Its basic operation is that based on the inputs, it emits a number n (cycles) of messages during the provided time to create a color transition at its output (RGBW transition of an LED strip).

The code I have is this:

var re0 = msg.payload.color.r0;
var gr0 = msg.payload.color.g0;
var bl0 = msg.payload.color.b0;
var wh0 = msg.payload.color.w0;

var re1 = msg.payload.color.r1;
var gr1 = msg.payload.color.g1;
var bl1 = msg.payload.color.b1;
var wh1 = msg.payload.color.w1;

var tim = msg.payload.control.t0;
var res = msg.payload.control.n0 - 1;
var sal = (tim / res) * 1000;
var cou = 0;

var rep = (re1 - re0) / res;
var grp = (gr1 - gr0) / res;
var blp = (bl1 - bl0) / res;
var whp = (wh1 - wh0) / res;

msg.payload.color.r0 = re0;
msg.payload.color.g0 = gr0;
msg.payload.color.b0 = bl0;
msg.payload.color.w0 = wh0;
node.send(msg);

setTimeout(sendmsg, sal);

function sendmsg() {
  if (cou++ < res) {
    setTimeout(sendmsg, sal);
    re0 += rep;
    gr0 += grp;
    bl0 += blp;
    wh0 += whp;
    msg.payload.color.r0 = Math.round(re0);
    msg.payload.color.g0 = Math.round(gr0);
    msg.payload.color.b0 = Math.round(bl0);
    msg.payload.color.w0 = Math.round(wh0);
    node.send(msg);
  }
}

Note, I am attaching the node alone, since neither the sender nor the receiver is necessary and I prefer not to complicate it further.

My problem, if I call it twice, it will mix the two loops (I send a red and a blue transition and they "fight" between them to send the message, flashing between red and blue until finished)

My intention is that if I call this node again it cancels its previous executions.

Can be done?

I appreciate any ideas.

If you mean cancels ongoing operations before restarting then it should be enough to store the timeout handle returned by setTimeout and call clearTimeout e.g:

clearTimeout(node.t1);
clearTimeout(node.t2);

node.t1 = setTimeout(sendmsg, sal);

function sendmsg() {
  if (cou++ < res) {
    node.t2 = setTimeout(sendmsg, sal);
    re0 += rep;
    gr0 += grp;
    bl0 += blp;
    wh0 += whp;
    msg.payload.color.r0 = Math.round(re0);
    msg.payload.color.g0 = Math.round(gr0);
    msg.payload.color.b0 = Math.round(bl0);
    msg.payload.color.w0 = Math.round(wh0);
    node.send(msg);
  }
}

If you mean sending a 2nd message stops (and doesnt restart the cycle) then:

if (node.t1 || node.t2) {
  clearTimeout(node.t1);
  clearTimeout(node.t2);
  node.t1 = null;
  node.t2 = null;
  return
}

node.t1 = setTimeout(sendmsg, sal);

function sendmsg() {
  if (cou++ < res) {
    node.t2 = setTimeout(sendmsg, sal);
    re0 += rep;
    gr0 += grp;
    bl0 += blp;
    wh0 += whp;
    msg.payload.color.r0 = Math.round(re0);
    msg.payload.color.g0 = Math.round(gr0);
    msg.payload.color.b0 = Math.round(bl0);
    msg.payload.color.w0 = Math.round(wh0);
    node.send(msg);
  } else {
    node.t1 = null;
    node.t2 = null;
  }
}

Hello, I have not understood you correctly, here are the codes with both versions, same error...

var re0 = msg.payload.color.r0;
var gr0 = msg.payload.color.g0;
var bl0 = msg.payload.color.b0;
var wh0 = msg.payload.color.w0;

var re1 = msg.payload.color.r1;
var gr1 = msg.payload.color.g1;
var bl1 = msg.payload.color.b1;
var wh1 = msg.payload.color.w1;

var tim = msg.payload.control.t0;
var res = msg.payload.control.n0 - 1;
var sal = (tim / res) * 1000;
var cou = 0;

var rep = (re1 - re0) / res;
var grp = (gr1 - gr0) / res;
var blp = (bl1 - bl0) / res;
var whp = (wh1 - wh0) / res;

msg.payload.color.r0 = re0;
msg.payload.color.g0 = gr0;
msg.payload.color.b0 = bl0;
msg.payload.color.w0 = wh0;
node.send(msg);

clearTimeout(node.t1);
clearTimeout(node.t2);

node.t1 = setTimeout(sendmsg, sal);

function sendmsg() {
  if (cou++ < res) {
    node.t2 = setTimeout(sendmsg, sal);
    re0 += rep;
    gr0 += grp;
    bl0 += blp;
    wh0 += whp;
    msg.payload.color.r0 = Math.round(re0);
    msg.payload.color.g0 = Math.round(gr0);
    msg.payload.color.b0 = Math.round(bl0);
    msg.payload.color.w0 = Math.round(wh0);
    node.send(msg);
  }
}
var re0 = msg.payload.color.r0;
var gr0 = msg.payload.color.g0;
var bl0 = msg.payload.color.b0;
var wh0 = msg.payload.color.w0;

var re1 = msg.payload.color.r1;
var gr1 = msg.payload.color.g1;
var bl1 = msg.payload.color.b1;
var wh1 = msg.payload.color.w1;

var tim = msg.payload.control.t0;
var res = msg.payload.control.n0 - 1;
var sal = (tim / res) * 1000;
var cou = 0;

var rep = (re1 - re0) / res;
var grp = (gr1 - gr0) / res;
var blp = (bl1 - bl0) / res;
var whp = (wh1 - wh0) / res;

msg.payload.color.r0 = re0;
msg.payload.color.g0 = gr0;
msg.payload.color.b0 = bl0;
msg.payload.color.w0 = wh0;
node.send(msg);

if (node.t1 || node.t2) {
  clearTimeout(node.t1);
  clearTimeout(node.t2);
  node.t1 = null;
  node.t2 = null;
  return
}

node.t1 = setTimeout(sendmsg, sal);

function sendmsg() {
  if (cou++ < res) {
    node.t2 = setTimeout(sendmsg, sal);
    re0 += rep;
    gr0 += grp;
    bl0 += blp;
    wh0 += whp;
    msg.payload.color.r0 = Math.round(re0);
    msg.payload.color.g0 = Math.round(gr0);
    msg.payload.color.b0 = Math.round(bl0);
    msg.payload.color.w0 = Math.round(wh0);
    node.send(msg);
  } else {
    node.t1 = null;
    node.t2 = null;
  }
}

Hello, I have found the solution, simply store the msgid in a node variable and compare it every cycle.

Adding these lines solved the problem:

var msguuid = __msgid__;                                              //here
flow.set("msguuid",msguuid);                                          //here

var color0r = msg.aic.color0.r;
var color0g = msg.aic.color0.g;
var color0b = msg.aic.color0.b;
var color0w = msg.aic.color0.w;

var color1r = msg.aic.color1.r;
var color1g = msg.aic.color1.g;
var color1b = msg.aic.color1.b;
var color1w = msg.aic.color1.w;

var transit = msg.aic.effect.transit;
var resolut = msg.aic.effect.resolut;
var numstep = transit * resolut;
var delstep = transit / numstep * 1000;
var counter = 0;

var step0_r = (color1r - color0r) / numstep;
var step0_g = (color1g - color0g) / numstep;
var step0_b = (color1b - color0b) / numstep;
var step0_w = (color1w - color0w) / numstep;

var msg = { aic: { color0:{}}};

sendmsg();

function sendmsg() {
  if (counter++ <= numstep && msguuid == flow.get("msguuid")) {       //here
    setTimeout(sendmsg, delstep);
    msg.aic.color0.r = Math.round(color0r);
    msg.aic.color0.g = Math.round(color0g);
    msg.aic.color0.b = Math.round(color0b);
    msg.aic.color0.w = Math.round(color0w);
    color0r += step0_r;
    color0g += step0_g;
    color0b += step0_b;
    color0w += step0_w;
    node.send(msg);
  }
}

I add, I have modified the input and output format to make it clean and be able to modify it more comfortably (I don't think it would be necessary to consider the equations)

Additionally, the resolution has gone from the total number of messages to the number of messages per second.