# How to "interact" with another instance of a function?

**URL:** <https://discourse.nodered.org/t/how-to-interact-with-another-instance-of-a-function/7045>\
**Category:** General\
**Created:** [20 January 2019 12:20 UTC](https://discourse.nodered.org/t/how-to-interact-with-another-instance-of-a-function/7045 "2019-01-20T12:20:26Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![hazymat](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hazymat/32/108159_2.png) [@hazymat](https://discourse.nodered.org/u/hazymat)\
**Post date:** [20 January 2019 12:20 UTC](https://discourse.nodered.org/t/how-to-interact-with-another-instance-of-a-function/7045/1 "2019-01-20T12:20:26Z")

</div>

(_Although what I'm trying to achieve can be done with core nodes, the reason I'd like to do this is to further my understanding of Javascript and Node-RED in general._)

I have written this little sleep dimmer function ([link to other forum post](https://discourse.nodered.org/t/show-and-tell-sleep-dimmer-lighting-audio-whatever/7041)), but I'd like to implement some kind of msg.reset to cancel the sleep dimmer.

Is there a way I can interact with the original "thread" or instance, to stop it, when the function itself receives a value in msg.reset?

(If you can correct any of my assumptions or wrong ideas about this, I'd be grateful too)

If not, is there a better way to achieve this?

---

<div class="post-metadata">

**Author:** ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)\
**Post date:** [20 January 2019 12:50 UTC](https://discourse.nodered.org/t/how-to-interact-with-another-instance-of-a-function/7045/2 "2019-01-20T12:50:46Z")

</div>

Assuming this `msg.reset` is being passed into the same node... then yes - you need to save the instance of the timeout `context.foo = setTimeout(....` then it will be available so you can call `clearTimeout(context.foo)`.

Of course this will mean you can only have one running at a time... so you may need to think how to handle that if another msg arrives to trigger another timeout... do you ignore it ? or cancel existing and restart ? or... up to you.

---

<div class="post-metadata">

**Author:** ![hazymat](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hazymat/32/108159_2.png) [@hazymat](https://discourse.nodered.org/u/hazymat)\
**Post date:** [20 January 2019 14:29 UTC](https://discourse.nodered.org/t/how-to-interact-with-another-instance-of-a-function/7045/3 "2019-01-20T14:29:19Z")

</div>

Thanks @dceejay. I'll go with one running at a time - I'd like to use the node status and I guess it would be impossible to show the status of multiple instances!

Will give that a go.

---

<div class="post-metadata">

**Author:** ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)\
**Post date:** [20 January 2019 14:59 UTC](https://discourse.nodered.org/t/how-to-interact-with-another-instance-of-a-function/7045/4 "2019-01-20T14:59:58Z")

</div>

Well yes. If it’s controllong one set of lights would be tricky to have two rodents running. So you need to block that from occurring.

---

<div class="post-metadata">

**Author:** ![hazymat](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hazymat/32/108159_2.png) [@hazymat](https://discourse.nodered.org/u/hazymat)\
**Post date:** [20 January 2019 22:46 UTC](https://discourse.nodered.org/t/how-to-interact-with-another-instance-of-a-function/7045/5 "2019-01-20T22:46:15Z")

</div>

> [@dceejay](#):
>
> save the instance of the timeout `context.foo = setTimeout(....` then it will be available so you can call `clearTimeout(context.foo)`

Just trying to get my head around this now.

Do you mean I should save a value into context to indicate that a given fadeout is running? Then look it up and clear the timeout? Or are you talking about storing the function itself in context? Can you give me a pointer as to how I might do that?

I've just read up on [storing a function in a variable](https://www.w3schools.com/js/js_function_definition.asp), but to be honest I don't fully understand.

---

<div class="post-metadata">

**Author:** ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)\
**Post date:** [20 January 2019 22:53 UTC](https://discourse.nodered.org/t/how-to-interact-with-another-instance-of-a-function/7045/6 "2019-01-20T22:53:21Z")

</div>

the instance of the timeout. Exactly as I wrote it

---

<div class="post-metadata">

**Author:** ![hazymat](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hazymat/32/108159_2.png) [@hazymat](https://discourse.nodered.org/u/hazymat)\
**Post date:** [20 January 2019 23:04 UTC](https://discourse.nodered.org/t/how-to-interact-with-another-instance-of-a-function/7045/7 "2019-01-20T23:04:02Z")

</div>

I think I've not understood, because this is now happening:

![fail](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/4/43dd0da5ef04cb2eab212330e50b8dd99e25962a.png)

Here's the code I changed it to:

```
if (msg.reset == "yep") {
    clearTimeout(context.foo)
}
    
setTimeout(function(){
    var i = startval;
    function f() {
        if (i>0) {
            i--;
            msg.payload = i;
            node.send(msg);
            var fadetxt = "Fading " + (i*steptime/1000).toString() + "s, " + i.toString() + "/" + startval.toString();
            node.status({fill:"green", shape:"ring", text:fadetxt});
        } else {
            node.status({});
            return;
        }
        context.foo = setTimeout( f, steptime );
    }
    f();
},initialdelay)
```

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [21 January 2019 07:18 UTC](https://discourse.nodered.org/t/how-to-interact-with-another-instance-of-a-function/7045/9 "2019-01-21T07:18:05Z")

</div>

You need to test whether msg.reset exists first, also consider whether you want to go on and restart the timer in the case of the reset message.

---

<div class="post-metadata">

**Author:** ![cflurin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cflurin/32/29_2.png) [@cflurin](https://discourse.nodered.org/u/cflurin)\
**Post date:** [21 January 2019 10:47 UTC](https://discourse.nodered.org/t/how-to-interact-with-another-instance-of-a-function/7045/10 "2019-01-21T10:47:54Z")

</div>

> [@dceejay](#):
>
> you need to save the instance of the timeout `context.foo = setTimeout(....` then it will be available so you can call `clearTimeout(context.foo)`

I thought we should use context.set() and context.get()

Something like this:

```auto
var id = setTimeout(...)
context.set('id', id);

and

var id = context.get('id');
clearTimeout(id);

```

---

<div class="post-metadata">

**Author:** ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)\
**Post date:** [21 January 2019 11:00 UTC](https://discourse.nodered.org/t/how-to-interact-with-another-instance-of-a-function/7045/11 "2019-01-21T11:00:27Z")

</div>

well yes that is "more correct" and would allow you to persist the object... but in this case I don't think persistence would be required so I think it's simper to understand.

---

<div class="post-metadata">

**Author:** ![cflurin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cflurin/32/29_2.png) [@cflurin](https://discourse.nodered.org/u/cflurin)\
**Post date:** [21 January 2019 11:16 UTC](https://discourse.nodered.org/t/how-to-interact-with-another-instance-of-a-function/7045/12 "2019-01-21T11:16:58Z")

</div>

Alright!  
One other benefit using context.set(): it is displayed in the menu Context Data.

---

<div class="post-metadata">

**Author:** ![hazymat](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hazymat/32/108159_2.png) [@hazymat](https://discourse.nodered.org/u/hazymat)\
**Post date:** [21 January 2019 16:33 UTC](https://discourse.nodered.org/t/how-to-interact-with-another-instance-of-a-function/7045/13 "2019-01-21T16:33:03Z")

</div>

I don't think I have a problem with the logic of testing for msg.reset, and knowing how to deal with different scenarios (e.g. discard, reset timer and start counting, etc.) but I am really struggling with how to clear the timeout.

I understand that I need to save the function into memory. I have chosen to save to **global** whilst I figure this out ( **just for my own testing and understanding** , as this means I can use context explorer to see it, and also access it from another node to e.g. test clearing the timeout from another function).

- My main function has a function within it, in order to be able to have 2 delays (initial delay, and repeating delay for each fading step).
- I have set the outer function (the initial delay) to memory.
- When I start the timer, I can use context explorer and I see "[Object Object]"

However when I load this back into memory from another function node, then clearTimeout, the fader just keeps going.

To make it clearer, here's my code (yes, I know I used "id", just ignore the name for now):

**FADER FUNCTION**

```
var id = setTimeout(function(){
    var i = startval;
    function f() {
        if (i>0) {
            i--;
            msg.payload = i;
            node.send(msg);
            var fadetxt = "Fading " + (i*steptime/1000).toString() + "s, " + i.toString() + "/" + startval.toString();
            node.status({fill:"green", shape:"ring", text:fadetxt});
        } else {
            node.status({});
            return;
        }
        setTimeout( f, steptime );
    }
    f();
},initialdelay)
global.set('id',id);

```

And then...

**TIMER CLEAR FUNCTION** (different node, which I can inject message to for testing)

```
var id = global.get('id');
clearTimeout(id);

```

When I inject a message into this second function, it carries on counting

---

<div class="post-metadata">

**Author:** ![cflurin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cflurin/32/29_2.png) [@cflurin](https://discourse.nodered.org/u/cflurin)\
**Post date:** [21 January 2019 17:22 UTC](https://discourse.nodered.org/t/how-to-interact-with-another-instance-of-a-function/7045/14 "2019-01-21T17:22:45Z")

</div>

You need to store the second setTimeout id:

```auto
var id = setTimeout(function(){
    var i = startval;
    function f() {
        if (i>0) {
            i--;
            msg.payload = i;
            node.send(msg);
            var fadetxt = "Fading " + (i*steptime/1000).toString() + "s, " + i.toString() + "/" + startval.toString();
            node.status({fill:"green", shape:"ring", text:fadetxt});
        } else {
            node.status({});
            return;
        }
        id = setTimeout( f, steptime );
        global.set('id',id);
    }
    f();
},initialdelay)
global.set('id',id);

```

BTW the `setTimeout` returns an ID:

> The clearTimeout() method clears a timer set with the setTimeout() method.
> 
> The ID value returned by setTimeout() is used as the parameter for the clearTimeout() method.

See [https://www.w3schools.com/jsref/met\_win\_cleartimeout.asp](https://www.w3schools.com/jsref/met_win_cleartimeout.asp)

---

<div class="post-metadata">

**Author:** ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)\
**Post date:** [21 January 2019 22:18 UTC](https://discourse.nodered.org/t/how-to-interact-with-another-instance-of-a-function/7045/15 "2019-01-21T22:18:25Z")

</div>

don't use global. It would mean you can only have one instance of your node (as they would all try to use the same global variable)... use a local context one instead.
