google apps 脚本是同步的吗?

Is google apps script synchronous?

我是一名 Java 开发人员,同时学习 JavaScript 和 Google Apps Script。作为新手,我学习了 JavaScript 的语法,而不是它的实际工作原理,我很高兴地使用 Google Apps Script 并按顺序和同步编写代码,就像 Java 一样。我所有的代码都是这样的:(大大简化以显示我的意思)

function doStuff() {
  var url = 'https://myCompany/api/query?term<term&search';
  var json = getJsonFromAPI(url);
  Logger.log(json);
}

function getJsonFromAPI(url) {
  var response  = UrlFetchApp.fetch(url);
  var json = JSON.parse(response);
  return json;
}

而且有效!它工作得很好!如果我不继续研究 JavaScript,我会说它就像发条一样运转。但是 JavaScript 不是发条装置,它是光荣的异步,据我所知,这根本不起作用,它会 "compile",但是记录 json 变量应该记录未定义,但它可以毫无问题地记录 JSON。

注意:

代码是在 Google Sheet 的脚本编辑器中编写和执行的。

这是为什么?

虽然 Google Apps 脚本 implements a subset of ECMAScript 5,但没有任何强制它是异步的。

虽然 JavaScript 的主要功能确实是它的异步特性,但 Google 开发人员似乎已经放弃了它,转而支持更简单、更直接的 API .

UrlFetchApp 方法是同步的。他们 return 一个 HttpResponse 对象,他们不接受回调。显然,这是一个 API 的决定。

请注意,自 introduction of V8 runtime for google app scripts 以来这并没有真正改变。

虽然我们使用的是最新最好的 ECMAScript 版本,运行 Promise.all(func1, func2) 我可以看到第二个函数中的代码在第一个函数完成后才会执行。

此外,还有仍然没有setTimeout()全局函数用于分支执行顺序。也没有任何 API 提供回调函数或类似承诺的结果。似乎 GAS 的理念是让一切同步。

我从 Google 的角度猜测,并行处理两个任务(例如,只有 Utilities.sleep(3000))需要多个线程来 运行服务器 cpu,它可能难以管理并且可能容易被滥用。

而在客户端或其他公司服务器上进行并行处理(例如,Node.js)则取决于该开发人员或用户。 (如果它们不能很好地扩展,那不是 Google 的问题)

但是有些东西使用并行


UrlFetchApp.fetchAll

UrlFetchApp.fetchAll() 将异步获取许多 url。虽然这不是您真正想要的,但获取 url 是寻求并行处理的主要原因。

我猜 Google 认为这没问题,因为 fetchall 正在使用网络客户端并且它自己的资源已经受配额保护。


FirebaseApp getAllData

我发现与使用电子表格存储数据相比,Firebase 速度非常快。您可以使用 FirebaseApp's getAllData:

一次从数据库中获取很多东西
function myFunction() {
  var baseUrl = "https://samplechat.firebaseio-demo.com/";
  var secret = "rl42VVo4jRX8dND7G2xoI";
  var database = FirebaseApp.getDatabaseByUrl(baseUrl, secret);

  // paths of 3 different user profiles
  var path1 = "users/jack";
  var path2 = "users/bob";
  var path3 = "users/jeane";

  Logger.log(database.getAllData([path1, path2, path3]));
}

HtmlService - IFrame 模式

HtmlService - IFrame mode 通过转到真正支持 promises 的客户端脚本并并行调用回服务器来允许完全的多任务处理。您可以从服务器启动此过程,但由于所有并行任务的结果都在客户端返回,因此不清楚如何将它们返回到服务器。您可以调用另一个服务器并发送结果,但我认为目标是首先将它们返回到调用 HtmlService 的脚本,除非您使用 beginRequestendRequest 类型架构。


tanaikech/RunAll

这是一个仅使用本机 Google Apps 脚本 (GAS) 运行 并发处理的库。该库声称通过 RunAll.Do(workers) 方法提供全面支持。


如果我发现任何其他技巧,我会更新我的答案。