Set Timeout in Google Apps Scripts
Asked Answered
R

5

35

Is it possible to call setTimeout or an equivalent function in Google Apps Scripts?

When I try to run the following code:

function onSubmit() {
  // we've been called, remove trigger, set timeout, re-enable, and then run function
  destroySubmitHandler();
  setTimeout(function() {
    createSubmitHandler();
    myFunction()
  }, 5 * 1000)
}

I get the following error:

screenshot

Receiptor answered 15/4, 2015 at 19:43 Comment(1)
SetTimeout is a browser function, not javascript thus undefined. Use sleep but will consume time quota.Nonpayment
R
53

Apparently you can use the function Utilities.sleep() like this:

function onSubmit() {
  // we've been called, remove trigger, set timeout, re-enable, and then run function
  destroySubmitHandler();
  Utilities.sleep(5 * 1000)
  createSubmitHandler();
  myFunction()
}
Receiptor answered 15/4, 2015 at 19:43 Comment(3)
Welcome back the land of synchronous javascript.Erichericha
Does Utilities.sleep() put the whole script to sleep, or just the function?Allergist
@user1063287, it immediately puts the script to sleep for the specified number of milliseconds.Biracial
B
7

you should try the specially designed function which is to resolve the problem of too much parallel submission:

function onSubmit(e) {
  var lock = LockService.getScriptLock();
  lock.waitLock(30000); // lock 30 seconds

  //do whatever you want here

  lock.releaseLock();
}

It is said the id would be the same without this lock with reference to google dev-document: https://developers.google.com/apps-script/reference/lock/lock

for example, the following is an apps script standalone web-site function:

google.script.run.withSuccessHandler(ready).logNow(email);

I lock it each time the google sheet updating the sheet in case there are multiple guys update it in the same time, or otherwise, the data might overwrite each other:

  var ls = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("logged");
  lock.waitLock(30000);
  ls.getRange(ls.getLastRow()+1, 1).setValue(email);
  lock.releaseLock();

although the 30 seconds seems a lot, once the setValue() function is down, the lock would be released. If you can read Chinese, I recommend this article: https://www.wfublog.com/2017/03/google-apps-script-spreadsheet-delay-write-data.html

Bout answered 9/3, 2019 at 10:21 Comment(0)
S
2

You can define your own setTimeout function inside the Google Apps

function setTimeout(func, timeout) {
  // Logger.log("setTimeout");
  var lock = LockService.getScriptLock();
  lock.waitLock(timeout);
  
  func();

  lock.releaseLock();
}

function helloFun() {
  Logger.log("Hello world!");
}

setTimeout(function() { helloFun(); }, 500);
Stepchild answered 15/10, 2022 at 19:12 Comment(0)
V
0

I found this solution...

function one2() {
   texte = "yum";
   var out = new Promise(function(resolve, reject){
    Utilities.sleep(5000);
    resolve( hello_callback_func(texte) );
  });
   return out;
}
Vulcanology answered 10/2, 2023 at 22:0 Comment(0)
S
0

This solution was still missing:

ScriptApp.newTrigger("anotherFunction")
    .timeBased().after(5 * 1000)
    .create();
  • Please note max. 20 triggers per user per script (source)

  • anotherFunction is executed from scratch, no shared scope. If you want to share data, you could use PropertiesService.getScriptProperties().setProperty('key','value'); in your original function PropertiesService.getScriptProperties().getProperty('key'); in anotherFunction()

  • Please test when using very small values of .after(x) like 1 millisecond. I'm not sure it works

Swint answered 8/3, 2023 at 7:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.