Time delay in scripts

Viewing 4 reply threads
  • Author
    Posts
  • November 5, 2019 at 4:14 PM #37834

    Grant Anderson
    Participant

    Hi, I’m updating entries in my database and need to access an online barcode lookup system. It only allows lookups every 5 seconds so as not to overload the server. How can I add a time delay in a script? I tried using Javascript’s setTimeout which would call a function after a specified time but Tap Forms compiler doesn’t seem to understand that. Any ideas?

    November 5, 2019 at 7:10 PM #37838

    Sam Moffatt
    Participant

    The only way I can think of would be to create a busy loop and check to see if time has elapsed. Something like this should work:

    function delay(duration)
    {
    	let now = new Date();
    	let future = now.getTime() + duration;
    	while((new Date()).getTime() < future) { }
    }
    
    function Timer() {
    	console.log(new Date());
    	delay(5000);
    	console.log(new Date());
    }
    
    Timer();

    Sample Execution:

    Tue Nov 05 2019 17:58:36 GMT-0800 (PST)
    Tue Nov 05 2019 17:58:41 GMT-0800 (PST)

    There might be a better way but this will work in a pinch.

    You might want to push the logic for the delay into the method call itself. If this is running inside a big loop, it should work ok. If you have multiple field scripts that you’re executing then I’m not sure this will be as effective so give it a try first:

    var lastCalled = 0;
    
    function delay(duration)
    {
    	let now = new Date();
    	let future = now.getTime() + duration;
    	while((new Date()).getTime() < future) { }
    }
    
    function rateLimitedLogger(message, minTime = 5000)
    {
    	let now = (new Date()).getTime();
    	let nextExecution = lastCalled + minTime;
    	if (now < nextExecution)
    	{
    		console.log(<code>Waiting ${nextExecution - now}ms</code>);
    		delay(nextExecution - now);
    	}
    	lastCalled = (new Date()).getTime();
    	console.log(new Date() + ' ' + message);
    
    }
    
    function Timer() {
    	rateLimitedLogger('Message 1');
    	rateLimitedLogger('Message 2');
    	delay(3000);
    	rateLimitedLogger('Message 3');
    	delay(6000);
    	rateLimitedLogger('Message 4');
    }
    
    Timer();

    Sample output:

    Tue Nov 05 2019 18:05:40 GMT-0800 (PST) Message 1
    Waiting 4999ms
    Tue Nov 05 2019 18:05:45 GMT-0800 (PST) Message 2
    Waiting 2000ms
    Tue Nov 05 2019 18:05:50 GMT-0800 (PST) Message 3
    Tue Nov 05 2019 18:05:56 GMT-0800 (PST) Message 4
    

    Obviously you’d need to swap out the console logging for your own implementation. This should work fine though and you can see that in my case it works fine. The examples are:

    1. The first launch, should always run.
    2. An immediately following execution (should be max time though looks like we lost a millisecond)
    3. I put in a manual delay for 3000 ms to demonstrate it properly accounting for that as the offset of 2000ms.
    4. I put in a manual delay for 6000 ms to demonstrate it properly accounting for being able to run immediately.

    Depending on what you’re doing, you might want to set the last called variable from another record somewhere and update it as you’re going. This would be important for if you are changing fields that are being watched by field scripts however this sort of script will pause TF because of the nature of how it’s running.

    Are you using a form script for this that you manually execute or field scripts?

    November 6, 2019 at 11:58 AM #37862

    Grant Anderson
    Participant

    Thanks Sam! That worked. Was hoping there was a built in function that didn’t freeze up the program similar to setTimeout. But this works well enough. Cheers!

    November 6, 2019 at 9:07 PM #37886

    Sam Moffatt
    Participant

    Even if setTimeout existed, it’d require the Javascript execution to be fully async but that would then cause potential race conditions with other scripts executing and changing values. It might make sense for form scripts but making that async in an environment like Tap Forms is a recipe for hard to debug issues that would make any seasoned operations person have nightmares.

    I have a similar use case of a large amount work that a form script is doing which pauses Tap Forms due to doing heavy network I/O. Some sort of progress bar interface that I could use to at least communicate where it’s at and maybe do a clean cancellation would be useful.

    November 7, 2019 at 9:19 AM #37902

    Grant Anderson
    Participant

    Agreed! And yeah, I’m using it as a form script as it is post-processing hundreds of records based on web lookups.

Viewing 4 reply threads

You must be logged in to reply to this topic.