问题描述
我想知道这是否与 Google Apps 脚本特别繁忙的时间有关,因为它似乎与更新 formResponse[] 数组长度的(偶尔)延迟有关.我正在使用以下代码来获取由表单提交触发的最新响应:
I'm wondering if this has to do with particularly busy times for Google Apps Script, because it seems like it has to do with an (occasional) delay in updating the length of a formResponse[] array. I'm using the following code to get the latest response triggered by a form submit:
var form = FormApp.getActiveForm();
var formResponses = form.getResponses();
var formResponse = formResponses[formResponses.length-1]; //latest response only
Logger.log('begin length: ' + formResponses.length);
然后我的脚本的其余部分与 formResponse[] 数组中的答案进行交互.有时,我会注意到它在最新响应之前得到了响应.我可以验证这一点,因为带有表单回复的电子表格显示了实际的最新回复.我的脚本需要 5-15 秒来执行,所以我在代码末尾有以下几行来再次检查数组的长度:
Then the rest of my script interacts with the answers in the formResponse[] array. Occasionally, I'll notice that it has gotten the response before the latest response. I can verify this because the spreadsheet with the form responses shows the actual latest response. My script takes 5-15 seconds to execute, so I I have the following lines at the end of my code to double check the length of the array again:
var form2 = FormApp.getActiveForm();
var formResponses2 = form2.getResponses();
Logger.log('end length: ' + formResponses2.length);
并且在日志中我会注意到第二个比第一个大一个(第二个是正确的值).我还没有真正发现它何时发生的太多模式,但它似乎在太平洋标准时间上午 7 点到 9 点之间更频繁地发生.现在我已经添加了一个 Utilities.sleep(5000)
作为函数的第一行,以便在我得到响应之前让表单有时间更新,到目前为止我还没有任何n-2 响应,这让我认为有某种延迟导致表单在表单提交"触发器触发后记录最新响应.
and in the log I'll notice that the second one is one greater than the first (and the second one is the correct value). I haven't really found much pattern as to when it happens, but it seems to happen more often between the hours of 7-9am PST. For now I've added a Utilities.sleep(5000)
as the first line in the function to allow time for the form to update before I get the responses, and so far I haven't had any n-2 responses, which makes me think there is some sort of delay causing the form to record the latest response after the "on form submit" trigger fires.
有没有其他人遇到过类似的事情?
Has anyone else encountered anything similar?
推荐答案
当服务器繁忙时,这些种族条件将变得更加明显,但对于云计算来说,它们只是照常营业.简而言之,文档的每个用户都有该文档的视图(副本),不能保证始终与主版本"相同.当您查看电子表格时,您正在查看您自己的电子表格副本.您的合作者可能正在查看他们自己的副本.事实上,访问电子表格"的触发器函数也将获得其自己的副本.任何地方所做的更改都需要任何地方同步,这需要时间.
When servers are busy, these race conditions will become more pronounced, but they are simply business as usual for cloud computing. In a nutshell, each user of a document has a view (copy) of that document, which cannot be guaranteed to be identical to a "master version" all the time. When you look at a spreadsheet, you are looking at your own copy of that spreadsheet. Your collaborator might be looking at their own copy. A trigger function accessing "the spreadsheet" will, in fact, be given its own copy as well. Changes made anywhere need to be synchronized everywhere, and that takes time.
在这种情况下,您的代码表明您在 Google 表单中包含的脚本中有一个函数.该脚本在触发时将获得一份表格副本,包括过去的回复.但是,触发脚本的表单提交可能尚未与表单提交同步.您还在使用包含回复的电子表格...当表单提交到表单服务时,它们会存储在表单服务中,并且它们也存储在电子表格的副本中.该操作可能会触发电子表格表单提交事件,并且(您的头还痛吗?) 函数将获得一份电子表格副本,该副本可能尚未包含新的表单提交数据!
In this case your code indicates that you have a function in a script that is contained in a Google Form. That script, when triggered, will be given a copy of the Form, including past responses. However, the form submission that triggered the script may not be synchronized with the form submission yet. You're also working with a spreadsheet that contains responses... when forms are submitted to the Form Service, they are stored in the Forms Service and they are also stored in a copy of the spreadsheet. That action may trigger a Spreadsheet Form Submission event, and (is your head sore yet?) that function will be given a copy of the spreadsheet that might not yet contain the new form submission data!
那么,该怎么办?
假设您使用触发器函数来处理表单响应.
Let's assume you're using a trigger function to handle form responses.
function handleForm( event ) {
...
}
如果您只需要处理当前表单响应",您应该使用传递给触发器的事件信息,而不是阅读电子表格或查询表单响应.通读了解事件,了解哪些事件信息提供给您的特定类型的触发器正在处理.(额外的好处:使用 event 参数可以让您免于调用服务 API,从而使您的函数更快.)
If you only need to process the "current form response", you should use the event information that is handed to the trigger, rather than reading the spreadsheet or querying the form responses. Read over Understanding Events to see what event information is provided to the specific type of trigger you're dealing with. (Added bonus: using the event parameter saves you from calling the services APIs, which makes your function faster.)
function handleForm( event ) {
var formResponse = event.response; // The response that triggered this
// function is in the event
...
}
我建议你也看看如何在 GAS 中测试触发功能?".
这篇关于获取最新的表单响应有时会获取之前的表单响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!