函数应用脚本的异步执行

eki*_*iim 10 asynchronous callback promise google-apps-script

我一直在挖掘,但找不到关于如何在 Google App Script 中使用异步函数的参考或文档,我发现人们提到这是可能的,但没有提到如何...

有人可以指出我正确的方向或为我提供一个例子吗?承诺、回调或其他可以帮助我解决这个问题的东西。

我有这个函数可以调用它foo需要一段时间才能执行(足够长的时间它可能会超时 HTTP 调用)。

我想要做的是重构它,它的工作方式是这样的:

function doPost(e) {
    // parsing and getting values from e
    var returnable = foo(par1, par2, par3);
      return ContentService
             .createTextOutput(JSON.stringify(returnable))
             .setMimeType(ContentService.MimeType.JSON);
}

function foo(par1, par2, par3) {
    var returnable = something(par1, par2, par3); // get the value I need to return;

    // continue in an Async way, or schedule execution for something else
    // and allow the function to continue its flow
    /* async bar(); */

    return returnable;
}
Run Code Online (Sandbox Code Playgroud)

现在我想意识到这一点,foo因为它需要很长时间而且我不想冒险超时,而且发生在那里的逻辑完全独立于客户端,所以没关系,我只需要返回值,我之前会得到。

另外,我认为值得一提的是,它作为网络应用程序部署在 Google Drive 中。

这已经很久了,但是添加一些上下文,在那一刻我想安排在 Google Drive 上发生的几件事,并且它正在超时执行,所以我正在寻找一种安全安排工作的方法

Tan*_*ike 10

  • 您想通过使用 Google Apps 脚本的异步处理来执行功能。
  • 您想使用时间触发器通过异步处理运行函数。

如果我的理解是正确的,不幸的是,没有直接实现它的方法和官方文档。但作为一种变通方法,这可以通过使用 Google Apps Script API 和 fetchAll 方法来实现,该方法可以通过异步处理工作。

此变通方法的流程如下。

  1. 部署 API 可执行文件,启用 Google Apps Script API。
  2. 使用 fetchAll 请求 Google Apps Script API 的端点以运行函数。
    • 当一次请求多个函数时,这些函数通过 fetchAll 进行异步处理。

笔记:

  • 我认为也可以使用 Web Apps 代替 Google Apps Script API。
  • 为了简单地使用这个解决方法,我创建了一个GAS 库。我认为你也可以使用它。
  • 在此变通方法中,您还可以使用时间触发器通过异步处理运行函数。

参考:

如果我误解了你的问题,我很抱歉。


sma*_*c89 8

借助新的V8 运行时,现在可以在应用程序脚本中编写异步函数并使用 Promise。

甚至触发器也可以声明为异步!例如(打字稿):

async function onOpen(e: GoogleAppsScript.Events.SheetsOnOpen) {
    console.log("I am inside a promise");
    // do your await stuff here or make more async calls
}
Run Code Online (Sandbox Code Playgroud)

要开始使用新的运行时,只需遵循本指南即可。简而言之,这一切都归结为将以下行添加到您的appsscript.json文件中:

{
  ...
  "runtimeVersion": "V8"
}
Run Code Online (Sandbox Code Playgroud)

  • 您可以将它们声明为异步..但它们仍然同步执行,因此这并不能真正解决问题..一定喜欢应用程序脚本。请参阅我的答案 /sf/ask/2186897751/#answer-60174689 (2认同)

Ste*_*las 6

还有另一种方法可以实现这一点。

您可以使用基于时间的一次性触发器异步运行函数,它们需要一些时间来排队(30-60 秒),但它非常适合您想从主要执行中删除的慢速任务脚本。

// Creates a trigger that will run a second later
ScriptApp.newTrigger("myFunction")
  .timeBased()
  .after(1)
  .create();
Run Code Online (Sandbox Code Playgroud)

有一个方便的脚本,我放在一起调用Async.gs,将有助于从这种技术中删除样板。您甚至可以使用它通过CacheService传递参数。

链接在这里:

https://gist.github.com/sdesalas/2972f8647897d5481fd8e01f03122805

// Creates a trigger that will run a second later
ScriptApp.newTrigger("myFunction")
  .timeBased()
  .after(1)
  .create();
Run Code Online (Sandbox Code Playgroud)

  • 首先,这是一个很棒的库,可以包含在您的项目中,使用起来再简单不过了。我想提出一个问题,最近我发现执行此库导致的周期性错误“例外:时钟事件必须至少间隔 1 小时安排。”有所增加。令人困惑的是,它并不一致,它似乎只是随机发生的。还有其他人看到这个问题吗? (2认同)