Google Apps 脚本竞争条件处理

问题描述 投票:0回答:1

我有一个可供多人编辑的电子表格。作为电子表格的一部分,我有一个脚本,当该行上的复选框设置为 true 以开始内部跟踪过程时,该脚本会将一些数据从一张纸复制到另一张纸上。

function onEdit(e){
  //get the sheet where the edit occurs
  var ss = SpreadsheetApp.getActive();
  var sourceSheet = e.range.getSheet();  
  var sourceRange = e.range;
  var sourceRow = sourceRange.getRow();
  var sourceColumn = sourceRange.getColumn();

  if((sourceSheet.getName() == "ScriptTestingSource") && 
  e.range.columnStart==18 && e.range.rowStart >= 2){
    if(e.value == "TRUE"){
      var targetSheet = ss.getSheetByName("ScriptTestingTarget");

      var sourceValues = sourceSheet.getRange(sourceRow,1,1,11).getValues();
      //splice off unneeded values
      sourceValues[0].splice(7,1)
      sourceValues[0].splice(3,2)
      sourceValues[0].splice(0,1)
    
      //insert new row on on target sheet
      var targetRows = targetSheet.getDataRange().getNumRows()
      targetSheet.insertRowsAfter(targetRows,1);
      targetSheet.getRange(targetRows+1,1,1,7).setValues(sourceValues)
    }
  }
}

现在,这对我来说非常适合执行从一行复制必要数据、修剪其余数据并将其插入到另一张纸上的新行的单一任务。但是,我正在尝试扩展功能,并解决用例的一些问题,例如如果有人快速将多行标记为 true。与谷歌服务器的通信延迟导致了我想解决的竞争条件。随着板材尺寸的增大,发生这种情况的风险也会增加。我对此可能的解决方案是什么?

我在想,也许不是在 onEdit 函数中完成工作,而是简单地将“工作订单”推送到一个数组,该数组将充当队列,在完成后将工作订单从数组中弹出。希望这可以让更多的工作添加到队列中,因为它有效。

var workQueue = [];
var working = false;

function onEdit(e){
  var ss = SpreadsheetApp.getActive();
  var sourceSheet = e.range.getSheet();  
  var sourceRange = e.range;
  var sourceRow = sourceRange.getRow();
  var sourceColumn = sourceRange.getColumn();
  if((sourceSheet.getName() == "ScriptTestingSource") && 
  e.range.columnStart==18 && e.range.rowStart >= 2){
    if(e.value == "TRUE"){
      workQueue.push([0,sourceSheet,sourceRange,sourceRow,sourceColumn])
      if(workQueue.length<1 && working==false){
        doWork();
      }
    }
  }
}
function doWork(){
  working=true;
  while(workQueue.length>0){
    workOrder = workQueue[0]
    switch(workOrder[0]){
      //0: copy data for carrier tracking to sheet
      case 0:
        //copy data to sheet order
        var sourceSheet = workOrder[1];
        var sourceRange = workOrder[2];
        var sourceRow = workOrder[3];
        var sourceColumn = workOrder[4];
      

        //get values from sheet
        var sourceValues = sourceSheet(sourceRow,1,1,11);
        //trim and clean data
        sourceValues[0].splice(7,1);
        sourceValues[0].splice(3,2);
        sourceValues[0].splice(0,1);

        //insert new row in target sheet
        var targetSheet = ss.getSheetByName("ScriptTestingTarget");
        var targetRows = targetSheet.getDataRange().getNumRows();
        targetSheet.insertRowsAfter(targetRows,1);
        targetSheet.getRange(targeRows+1,1,1,7).setValues(sourceValues);
        workQueue.pop();
        break;
      default:
        break;
    }
  }
  working=false;
}

有这样的事吗?虽然上面的例子实际上不起作用。

javascript google-apps-script google-sheets triggers
1个回答
0
投票

问题是 onEdit 在同时编辑或快速编辑期间甚至不会触发。唯一可能起作用的是 onEdit 内部,您检查所需工作表的所有行并执行必要的操作。更好的方法是不依赖 onEdit 触发器,而是使用菜单功能或按钮。

© www.soinside.com 2019 - 2024. All rights reserved.