我正在向我的Web应用发送5个请求:
import requests
backodds = "3.00"
layteam = "Flamengo"
layodds = "1.50"
advantage = "25.55"
webAppsUrl = "https://script.google.com/macros/s/XXXX/exec"
for i in range(5):
requests.get(webAppsUrl + "?backteam=" + str(i) + "&backodds=" + backodds + "&layteam=" + layteam + "&layodds=" + layodds + "&advantage=" + advantage)
如果我可以等待每个请求执行,我可以这样离开我的Web应用程序:
function doGet(e) {
const lock = LockService.getDocumentLock();
if (lock.tryLock(360000)) {
try {
var backteam = e.parameter.backteam;
var backodds = e.parameter.backodds;
var layteam = e.parameter.layteam;
var layodds = e.parameter.layodds;
var advantage = e.parameter.advantage;
Utilities.sleep(30000) // I swapped the tasks for a sleep just for testing
var second_sheet = SpreadsheetApp.openById('XXXXXXX');
var second_sheet_page = second_sheet.getSheetByName('STACKTEST');
var r = 1;
while (second_sheet_page.getRange(r, 1).getValue()) {
r++;
}
second_sheet_page.getRange(r, 1, 1, 5).setValues([[backteam,backodds,layteam,layodds,advantage]]);
} catch (e) {
//pass
} finally {
lock.releaseLock();
}
} else {
//pass
}
}
由于我不想等待每个请求完成执行(因 for each 请求都需要30秒以上,而且我不在乎执行期间和之后会发生什么),因此我正在 for each 请求创建一个触发器:
var RECURRING_KEY = "recurring";
var ARGUMENTS_KEY = "arguments";
function setupTriggerArguments(trigger, functionArguments, recurring) {
var triggerUid = trigger.getUniqueId();
var triggerData = {};
triggerData[RECURRING_KEY] = recurring;
triggerData[ARGUMENTS_KEY] = functionArguments;
PropertiesService.getScriptProperties().setProperty(triggerUid, JSON.stringify(triggerData));
}
function handleTriggered(triggerUid) {
const lock = LockService.getDocumentLock();
if (lock.tryLock(360000)) {
var scriptProperties = PropertiesService.getScriptProperties();
var triggerData = JSON.parse(scriptProperties.getProperty(triggerUid));
var second_sheet = SpreadsheetApp.openById('XXXXXX');
var second_sheet_page = second_sheet.getSheetByName('StackOverflow');
var r = 1;
while (second_sheet_page.getRange(r, 1).getValue()) {
r++;
}
var to_sheet = [
[triggerData.arguments[0],triggerData.arguments[1],triggerData.arguments[2],triggerData.arguments[3],triggerData.arguments[4]]
];
Utilities.sleep(30000) // I swapped the tasks for a sleep just for testing
second_sheet_page.getRange(r, 1, to_sheet.length, to_sheet[0].length).setValues(to_sheet);
} else {
console.error("Timeout");
}
if (!triggerData[RECURRING_KEY]) {
deleteTriggerByUid(triggerUid);
}
return triggerData[ARGUMENTS_KEY];
}
function deleteTriggerArguments(triggerUid) {
PropertiesService.getScriptProperties().deleteProperty(triggerUid);
}
function deleteTriggerByUid(triggerUid) {
if (!ScriptApp.getProjectTriggers().some(function(trigger) {
if (trigger.getUniqueId() === triggerUid) {
ScriptApp.deleteTrigger(trigger);
return true;
}
return false;
})) {
console.error("Could not find trigger with id '%s'", triggerUid);
}
deleteTriggerArguments(triggerUid);
}
function deleteTrigger(trigger) {
ScriptApp.deleteTrigger(trigger);
deleteTriggerArguments(trigger.getUniqueId());
}
function doGet(e) {
var trigger = ScriptApp.newTrigger("triggerfunct").timeBased()
.after(1)
.create();
setupTriggerArguments(trigger, [e.parameter.backteam, e.parameter.backodds, e.parameter.layteam, e.parameter.layodds, e.parameter.advantage], false);
}
function triggerfunct(event) {
var functionArguments = handleTriggered(event.triggerUid);
console.info("Function arguments: %s", functionArguments);
}
但目前的结果是,除了不考虑发送数据的顺序外,还注意到值是叠加的,而不是放在不同的行上,即使我在文档上放置了锁,这样就不会发生这种情况.
我的预期结果是:
有没有办法解决这些问题?
我真正需要的是通过requests
激活GAS中的代码,但我不想等到每次执行完整个代码后,才完成requests
.
换句话说,我想在GAS中激活任意次数的代码,必要时生成一个执行队列,然后继续我的生活,而不用担心执行需要多长时间.
例如,在Python中使用subprocess
将requests
放在后台,我不能这样做,因为它将继续执行,这会显著增加每月的成本,因此我真正需要的是一种完全取消GAS执行与所做请求之间的链接的方法.
为了加快进程,我修改了代码:
var second_sheet = SpreadsheetApp.openById('XXXXXXX');
var second_sheet_page = second_sheet.getSheetByName('STACKTEST');
var r = 1;
while (second_sheet_page.getRange(r, 1).getValue()) {
r++;
}
second_sheet_page.getRange(r, 1, 1, 5).setValues([[backteam,backodds,layteam,layodds,advantage]]);
至(Enable the Google Sheets API advanced service):
var sheet_id = 'XXXXXXX';
var sheet = SpreadsheetApp.openById(sheet_id);
var sheet_page = sheet.getSheetByName('STACKTEST');
var avals = Sheets.Spreadsheets.Values.get(sheet_id, 'STACKTEST!A1:A').values;
var r = avals.length + 1;
var to_sheet = [
[triggerData.arguments[0],triggerData.arguments[1],triggerData.arguments[2],triggerData.arguments[3],triggerData.arguments[4]]
];
sheet_page.getRange(r, 1, to_sheet.length, to_sheet[0].length).setValues(to_sheet);
Test reduce time
当填充12800行时,使用第一种方法(因此在第12801行中添加值):
Timeout Error (exceeded the 6 minute runtime limit)
使用Google Sheets API:
804ms
当填充1000行时,使用第一种方法(因此在第1001行中添加值):
3493ms
使用Google Sheets API:
833ms