Skip to main content
March 10, 2014
Question

Anything similar to javascript's setInterval in ExtendScript?

  • March 10, 2014
  • 4 replies
  • 9034 views

I need a way to poll my server for new jobs for the illustrator script to work on every few hours.

I tried with $.sleep(), but that is blocking, I need a non-blocking way to do this.

Any advice?

Thanks!

Kashmira

This topic has been closed for replies.

4 replies

Inventsable
Legend
February 3, 2019

Just to clarify, you can do this with a simple CEP panel. I don't know of a way to accomplish it with only .JSX, I tried the methods above as a new member and was discouraged since I couldn't get them to reliably work and others above say it's not possible with "JS" though it is as long as you're using CEP and running a simple CSInterface.evalScript function via setInterval.

Apparently Adobe forums doesn't accept text copied from VSCode. When I try to use the standard syntax highlighting feature here, it breaks and just gives me this:

// In CEP while using a Vue CDN:

Vue.component('timer', {

  data() {

   return {

   // Initialize data object for selection:

  selection: {

  timer: null,

  data: null,

  last: null,

  interval: 200,

  }

  }

  },

  mounted() {

   // When component is mounted, start a timer

   this.startTimer(this.selection)

  },

  methods: {

   startTimer(target) { target.timer = setInterval(this.selectionCheck, target.interval); },

   // The timer above runs the below code every 200ms

   selectionCheck() { csInterface.evalScript('scanSelection()', this.selectionRead); },

   // The check above returns a very simple value and calculation, only measuring for change with previous state.

   selectionRead(msg) {

   // If there is a change between this state and previous:

   if (this.selection.last !== msg) {

   // Then assign previous to this state

   this.selection.last = msg;

   // And now we know the state has been changed, use this as the trigger for a larger event.

  } else {

   // Nothing should happen, no change in selection or state.

  }

  }

  }

})

And on the JSX side, the function being called by the timer every 200ms:

function scanSelection() {

   var doc = app.activeDocument;

   var result = [];

   if (doc.pageItems.length) {

   for (var i = 0; i < doc.pageItems.length; i++) {

   var child = doc.pageItems;

   if (child.selected)

   result.push(i);

   }

   }

   if (doc.textFrames.length) {

   for (var i = 0; i < doc.textFrames.length; i++) {

   var child = doc.textFrames;

   if (child.selected)

   result.push(i);

   }

   }

   return result;

}

Which inevitably returns data to the selectionRead function in the original timer. Note that it doesn't have to be the selection count here, you can use a timer to measure any property accessible via scripting in this way, so you can easily create your own custom event listeners via running rudimentary checks.

ahmedk8610729
Participant
August 8, 2018

If you use $.sleep() in ExtendScript then it will block. If you want to create a feature like JavaScript setInterval then you will have to use onIdle event. It triggers on software IDLE time but it there is much more to it. You can check for system state in really short and long amounts of time. It will then return it to you and that is the interval.

Try the sample code:

function main() {
var myIdleTask = app.idleTasks.add({
name: “my_idle_task”,
sleep: 1000
});
var onIdleEventListener = myIdleTask.addEventListener(IdleEvent.ON_IDLE, onIdleEventHandler, false);
}
// SETINTERVAL DOSNT EXIST SO WE USE THE ONLY POSSIBLE WAY ONIDLE EVENT:
function onIdleEventHandler(myIdleEvent) {
var myTextFrames = app.activeDocument.pages.item(0).textFrames;
mimWinPnl.pgr.value +=1;
if(mimWinPnl.pgr.value > 99){ // progress bar value
//Delete idle task by setting its sleep time to zero.
myIdleEvent.parent.sleep = 0;
}
}

I hope it helps you !

Silly-V
Legend
August 8, 2018

That doesn't look like it's for Illustrator.

CarlosCanto
Community Expert
Community Expert
August 9, 2018

it is not...

...inDesign?

Matthias Guntrum
Participant
April 28, 2014

Hi,

I needed setInterval functionality and emulated it with the following snippet using app.scheduleTask();

Please note that i programmed with Adobe After Effects as my target application.

Gtlym = new Object();

Gtlym.CALL = new Object();

Gtlym.guid = function() {

     var s4 = function() { return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1); };

     return s4() + s4() + s4() + s4()  + s4()  + s4() + s4() + s4();

}

Gtlym.setInterval = function(func,millis){

     this.guid = Gtlym.guid();

     Gtlym.CALL["interval_"+this.guid] = func;

     app.scheduleTask('Gtlym.CALL["interval_'+this.guid+'"]();',millis,true);

}

//Example:

Gtlym.setInterval(function(){/*your code here*/},1000);

Cheers,

Matthias

gentlymad.org - Matthias Guntrum

Inspiring
March 10, 2014

I have often wondered the same thing and researched it pretty extensively but to no avail. I am still wondering if there is some hack approach using dates, loops or practically anything to make a home brewed interval timer. But it seems like no. Even using Date for checking pretty much ends up emulating $sleep() from my tests. Why Adobe omitted common timers and intervals from the internal JS is beyond me, setInterval and setTimeout would be so useful, likewise the lack of mouse events, both those would open up entire new worlds of possibilities.

Here is a thread in the InDesign forum speaking of "app.scheduleTask" using Bridge: app.scheduleTask(script, delay [, repeat])

http://forums.adobe.com/message/3706907#3706907

I tried the "app.scheduleTask" approach and never got it working in Illustrator however. <-- I hope someone proves otherwise and says it is possible in Illustrator, please let me know if you do. Otherwise I don't think there are any solutions via JS. Maybe a timer in Applescript or VBScript however running in the background and working with Illustrator externally would be an alternative.

March 12, 2014

Thank you! I will try using scheduleTask and update this thread on my findings.