Is there an equivalent to Javascript setTimeout?

Does anybody know - Is there an equivalent to the the JavaScript setTimeout() method in Groovy / Hubitat?

Specifically, I am looking for something that you can set to run a method on expiration of the timer, but which returns a handle so that the timer can then be manipulated like you can in JavaScript by clearing the timeout (i.e., using something like JavaScript's clearTimeout() method).

I know about runIn and runInMillis but they don't return a handle that allows you to cancel them (my understanding is they have a void return type - please let me know if I'm wrong). My understanding is you can reset runIn and runInMillis by calling them with the same method as you originally called them with, but this restarts the time, rather than clears it.

Any help you can give is appreciated.

unschedule(String handlerMethod)

1 Like

Thank you. So as I undestand this, if I did

runIn(60, myHandlerMethodName)

I could then later cancel it with:

unschedule(myHandlerMethodName)

is that correct?

1 Like

yes

1 Like

Also, you should be aware of these two options:

runIn(60, myHandlerMethodName)

and

runIn(60, myHandlerMethodName, [overwrite: false])

overwrite:true is the default, so every time you run the first form of runIn, it unschedules any pending runIn for that handler. The second form doesn't unschedule, it creates a new scheduled event.

thanks for the help. Final question . . .
Let's say I have a method that takes a time value
def myMethod(time) { ... some code ... }

And I want to run several instances of it and be able to cancel . In Javascript, I could run each instance and assign the return handler to a variable in an array
instance[0] = setTimeout(myMethod(50), 3000)
instance [1] = setTimeout(myMethod(150), 4000)
instance[2] = setTimeout(myMethod(500), 9000)

I could then clear a specific one. I.e., clearTimeout(instance[1]) to clear the second one, but the first and third would continue.

Is the same achievable with unsubscribe() and runIn( time, myMethod, [data[time:whatever], overwrite:false]), or would each method name have to have a different name so that you clear the "right" one (or would the unsubscribe just clear all the myMethod runIns)?

You would need to handle the data passed in your code to decide what to do with that particular instance. You won't get help from unsubscribe() per se. But by passing data through the scheduler to the handler you can do what you need to do.

Sorry, I don't fully understand this. I don't want to use too much of your time on this - is there API documentation somewhere covering this and I'll just review that? What you've answered so far is very helpful (and already allows me to fix a problem I needed to address in some code I'm working on).
Thanks.

I don't know about the documentation.

You pass a map in for data, so it looks like this:

runIn(60, handler, [data:[x: 1, y: "abc", etc: etc]])

Then the handler is:

void handler(p) {
   p.x ... 
   p.y ...  
   p.etc
}
1 Like

Thanks. That's much clearer.

It would certainly have been nice if each call to runIn / runInMillis returned a unique handle, like you get in JavaScript's setTimeout, so you could uniquely identify and end timeouts, but what you've explained allows me to move ahead. If there were a reasonable way to modify it runIn/ runInMillis to be more "JavaScript" like -- i.e. so each call returned a unique handle to allow accurate identification and termination using a clearTimeout like function, please give that a thought (or, along the same lines, add additional methods following the JavaScript naming convention setTimeout(), clearTimeout()). In any case, I understand this may not be a priority given all the more major things your team is working on. Thanks again for the response.