google-apps-script - 确保执行 appendRow 并从最后一行返回数据,同时处理与谷歌应用脚本的并发性
问题描述
我有一个 html 表单,它获取数据(学生观察)并将该数据保存到电子表格中,它应该是一个函数。生成一个 id b. 将该行附加到电子表格(学生观察)中,包括 id c。通过检索保存在工作表 d 上的最后一个 id 来检查观察是否已保存(附加行)。如果生成的 id 与从最后一行检索到的 id 匹配,则返回保存的 id,否则返回 0
问题:
该代码大部分时间都有效,问题是有时用户会得到 0(而不是应该返回的 id),我不确定如果附加操作似乎没有失败,为什么会这样。
我的代码:
//save observacion submitted
function saveObservation(studentICID, studentOSISICID, studentName, studentClass, dateObserv, catObsev, textObserv, textCommit){
//return variable initialized
var success = 0;
//lock the app to deal with concurrency for 3 seconds
var lock = LockService.getPublicLock();
lock.waitLock(3000); // wait 3 seconds before conceding defeat.
try{
// Log the email address of the person running the script.
var submittedByEmail = Session.getActiveUser().getEmail().slice(0, Session.getActiveUser().getEmail().indexOf("@"));
var now = new Date();
//get current date/time
var dateTime = Utilities.formatDate(now, "GMT-5", "yyyy-MM-dd' 'HH:mm:ss");
//get the sheet to log observations
var sODA = ssODA.getSheetByName("Observaciones");
var rowsBeforeObservation = sODA.getLastRow();
//get observation id
var observID = getObservationID(studentICID, studentOSISICID);
//log observation
sODA.appendRow([observID, dateTime,submittedByEmail,studentICID,studentOSISICID,studentName,studentClass,dateObserv,catObsev,textObserv,textCommit]);
//log observation to Logger for backup
Logger.log([
observID,
dateTime,
submittedByEmail,
studentICID,
studentOSISICID,
studentName,
studentClass,
dateObserv,
catObsev,
textObserv,
textCommit
]);
//update spreadsheet
SpreadsheetApp.flush();
//check if observation was logged
var lastobservIDOnSheet = sODA.getRange(sODA.getLastRow(),1,1,1).getValue();
if(lastobservIDOnSheet == observID){
success = observID;
}
Logger.log('success: ' + success);
return success;
}catch(e){
//Logger.log("error in saveObservation: " + e);
var eventcode = "saveObsFailed";
var event = "failure";
log_event_text(eventcode,event,e)
}finally { //release lock
lock.releaseLock();
}
}
我试过的:
起初我以为我必须锁定保存操作,因为我认为这是并发问题,所以我添加了锁定部分
然后一位老师正在保存学生的观察结果并报告说它得到的是 0 而不是观察 id 所以我添加了电子表格刷新,如在这个类似的问题中所示
但同样,一位老师最近报告说得到了 0 并且日志证实了这一点(他是唯一一个使用 html 表单的人)。我不确定这个来自哪里,因为我什至自己测试过它,并且与其他用户一起工作过,也只有一个人保存,所以在这一点上我不确定我应该尝试什么或者我的锁/冲洗实施是错误的?
先感谢您。
解决方案
尝试在电子表格的写入和读取之间使用 SpreadsheetApp.flush()。
var lastobservIDOnSheet = sODA.getRange(sODA.getLastRow(),1).getValue();
问题可能是有时您没有收到 activeUsers 电子邮件
试试这种方式:
function saveObservation(studentICID, studentOSISICID, studentName, studentClass, dateObserv, catObsev, textObserv, textCommit) {
var success = 0;
var lock = LockService.getPublicLock();
lock.waitLock(3000); // wait 3 seconds before conceding defeat.
try {
var submittedByEmail = Session.getActiveUser().getEmail().slice(0, Session.getActiveUser().getEmail().indexOf("@"));
if (submittedByEmail) {
var now = new Date();
var dateTime = Utilities.formatDate(now, "GMT-5", "yyyy-MM-dd' 'HH:mm:ss");
var sODA = ssODA.getSheetByName("Observaciones");
var rowsBeforeObservation = sODA.getLastRow();
var observID = getObservationID(studentICID, studentOSISICID);
sODA.appendRow([observID, dateTime, submittedByEmail, studentICID, studentOSISICID, studentName, studentClass, dateObserv, catObsev, textObserv, textCommit]);
} else {
throw "Error: Getting Active User Email";
return 0;
}
SpreadsheetApp.flush();
var lastobservIDOnSheet = sODA.getRange(sODA.getLastRow(), 1).getValue();
if (lastobservIDOnSheet == observID) {
success = observID;
}
throw "Success"
return success;
} catch (e) {
throw e;
var eventcode = "saveObsFailed";
var event = "failure";
log_event_text(eventcode, event, e)
} finally { //release lock
lock.releaseLock();
}
}
推荐阅读
- android - react-native:无法连接到android上的开发服务器
- java - 使用 OpenJDK 7 时无法在 Eclipse 中打开 Maven
- mongodb - 为什么我的 mongodb 查询没有给我预期的结果?
- html - 当它是编码的 CSS 背景图像时如何更改 SVG 颜色?
- python - TextEdit 以编程方式设置文本而不触发 textChanged 事件?
- java - 访问spring bean代理引用本身
- python - 我的文件扩展名有什么问题(.ipynb,.py)
- android - 删除项目后Recyclerview不刷新
- azure - Azure 存储帐户,通过公共链接公开文件以下载文件
- java - 视频文件从 java 服务器流式传输到 iPhone