
- Post History
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
on ‎08-18-2019 06:55 PM
As gs.sleep() is undocumented, it is difficult to know quite how it works and if it ties up a thread unnecessarily (I suspect it does), so a good alternative if you're looking for an asynchronous wait server side is to use the schedule once script include (thanks to John Andersen for point this out).
gs.log('Started','Async example '+ Date.now());
var so = new ScheduleOnce();
so.script = "(function(){gs.log('I waited 5 seconds','Async example '+ Date.now())})()";
so.setAsSeconds(5);
so.schedule();
gs.log('Ended','Async example '+ Date.now());
- 9,309 Views
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Does this really work in serial though? I have some code I want to wait on, but if I call this example immediately, Servicenow loads this up into the queue but it might be processed after the work I had told Servicenow to do happens right?
gs.log('Started','Async example '+ Date.now());
var so = new ScheduleOnce();
so.script = "(function(){gs.log('I waited 5 seconds','Async example '+ Date.now())})()";
so.setAsSeconds(5);
so.schedule();
gs.log('Ended','Async example '+ Date.now());
//run my script ----- might happen before the Scheduleonce is finished.

- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
If your original script calling the ScheduleOnce is still running, you'll find this runs in parallel rather than in series. A five second wait makes that difficult to show, but it won't wait for the thread that called it, rather it will pick up the first available thread once the timer completes. You could try some variations, such as not including any seconds, etc, and writing to the logs and you should see that it works.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
You could also create a new table to store sys_ids or some reference back to the workflow, then once the script completes, add the original sys_id to the table, and have that trigger the original workflow to continue. It's more complicated, but it should help performance.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
if anyone else needs this... I like reusable code 🙂
Add Field "Data Loaded" with name "u_data_loaded" if you want the user to see.
client script:
function sleep(seconds) {
g_form.setValue('u_data_loaded', false); //OMIT IF NOT NEEDED
var ajax = new GlideAjax('sleepNow');
ajax.addParam('sysparm_name', 'sleep');
ajax.addParam('sysparm_seconds', 10);
ajax.getXML(checkit);
function checkit(response) {
var answer = response.responseXML.documentElement.getAttribute("answer");
alert("Loading of this week's data is complete.");
g_form.setValue('u_data_loaded', true); //OMIT IF NOT NEEDED
}
}
script include: (named - sleepNow)
var sleepNow = Class.create();
sleepNow.prototype = Object.extendsObject(AbstractAjaxProcessor, {
sleep: function() {
var sleepseconds = this.getParameter('sysparm_seconds') + '';
sleepseconds = parseInt(sleepseconds) * 1000;
gs.sleep(sleepseconds);
},
type: 'sleepNow'
});
I added a second onSubmit client script to prevent the user to be able to submit when it was still calculating.
function onSubmit() {
//Type appropriate comment here, and begin script below
var check = g_form.getValue('u_data_loaded') + '';
if(check == "false"){
alert("Sorry... still calculating time from tickets. Wait 5 seconds and try and save/update again.");
return false;
}
}