我是一名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不是一个时钟装置,它是非常异步的,从我的理解来看,这根本不应该工作,它会“编译”,但是记录json
变量应该记录undefined,但是它记录JSON没有问题。
注:
代码是在GoogleSheet的脚本编辑器中编写和执行的。
这是为什么呢?
3条答案
按热度按时间kuarbcqp1#
虽然Google Apps脚本implements a subset of ECMAScript 5,但没有任何东西强制它是异步的。
虽然JavaScript的主要功能是它的异步特性,但Google开发人员似乎已经放弃了这一点,转而支持更简单,更直接的API。
UrlFetchApp
方法是同步的。它们返回一个HttpResponse
对象,并且不接受回调。这显然是一个API的决定。ffx8fchx2#
请注意,自introduction of V8 runtime for google app scripts以来,这并没有真正改变。
当我们使用的是ECMAScript的最新版本,运行
Promise.all(func1, func2)
时,我可以看到第二个函数中的代码直到第一个函数完成后才会执行。此外,* 仍然 * 没有
setTimeout()
全局函数可用于分支执行顺序。也没有任何API提供回调函数或类似promise的结果。看起来GAS的哲学是让一切都同步。ymdaylpp3#
从Google的Angular 来看,并行处理两个任务(例如,简单地有
Utilities.sleep(3000)
)将需要在服务器cpu中运行多个线程,这可能是不可管理的,并且可能很容易被滥用。而客户端或其他公司服务器上的并行处理(例如例如,Node.js)取决于该开发人员或用户。(如果他们不能很好地扩展,这不是谷歌的问题)
然而,有些东西使用并行性
UrlFetchApp.获取全部
UrlFetchApp.fetchAll()将异步获取多个URL。虽然这不是你真正想要的,但是获取url是寻求并行处理的一个主要原因。
我猜Google的理由是这是可以的,因为
fetchall
使用的是Web客户端,它自己的资源已经受到配额保护。FirebaseApp getAllData
我发现Firebase与使用电子表格存储数据相比速度非常快。使用
FirebaseApp
的getAllData
可以一次从数据库中获得很多东西:HtmlService - IFrame模式
HtmlService - IFrame mode允许完全的多任务处理,它可以执行真正支持promise的客户端脚本,并并行调用服务器。您可以从服务器启动这个过程,但是由于所有并行任务的结果都在客户机中返回,因此不清楚如何将它们返回到服务器。您可以进行另一个服务器调用并发送结果,但我认为目标是让它们返回到最初调用
HtmlService
的脚本,除非您使用beginRequest
和endRequest
类型的体系结构。tanaikech/RunAll
这是一个仅使用本地Google Apps脚本(GAS)运行并发处理的库。这个库通过
RunAll.Do(workers)
方法声称完全支持。我会更新我的答案如果我发现任何其他的技巧。