谷歌应用脚​​本是同步的吗?

Gem*_*tic 7 javascript v8 google-apps-script

我是一名Java开发人员,同时学习JavaScript和Google Apps脚本.作为新手,我学习了JavaScript的语法,而不是它的实际工作方式,我很乐意在Google Apps脚本中删除并按顺序和同步编写代码,就像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;
}
Run Code Online (Sandbox Code Playgroud)

它的工作原理!它工作得很好!如果我不继续研究JavaScript,我会说它就像发条一样.但JavaScript不是一个发条,它是光荣的异步,根据我的理解,这根本不起作用,它会"编译",但记录json变量应该记录未定义,但它记录JSON没有问题.

注意:

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

为什么是这样?

Ste*_*las 14

请注意,自从为 google 应用程序脚本引入 V8 运行时以来,这并没有真正改变。

当我们使用最新最好的 ECMAScript 版本时,运行 aPromise.all(func1, func2)我可以看到第二个函数中的代码直到第一个函数完成才执行。

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

  • 奇怪的是他们发布了 v8,并且仍然使用这种奇怪的非异步方法来实现 ES6。这是他们实现与真正的 ES6 完全平价的机会。 (5认同)

Mad*_*iha 12

虽然Google Apps脚本实现了ECMAScript 5的子集,但没有任何东西强迫它是异步的.

虽然JavaScript的主要功能确实是它的异步性质,但谷歌开发人员似乎已经放弃了这一点,转而采用更简单,更直接的API.

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

  • 无需指定.没有api可以异步,如果它没有返回一个promise或接受一个回调,就这么简单. (4认同)
  • 这也让我的心乱了一段时间。现在我明白了 (2认同)

tod*_*dmo 5

我从谷歌的角度猜测,并行处理两个任务(例如,简单地有Utilities.sleep(3000))将需要在服务器 cpu 中运行多个线程,这可能无法管理并且可能很容易被滥用。

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

然而有些东西使用并行性


UrlFetchApp.fetchAll

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

我猜谷歌认为这是可以的,因为fetchall它使用的是网络客户端,并且它自己的资源已经受到配额的保护。


FirebaseApp 获取所有数据

我发现与使用电子表格进行数据存储相比,Firebase 速度非常快。FirebaseApp您可以使用'sgetAllData一次从数据库中获取许多内容:

function myFunction() {
  var baseUrl = "https://samplechat.firebaseio-demo.com/";
  var secret = /* your secret */;
  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]));
}
Run Code Online (Sandbox Code Playgroud)

HtmlService - IFrame 模式

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


塔奈克什/RunAll

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


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