简体   繁体   English

Google Apps 脚本是否有承诺?

[英]Are there promises on Google Apps Script?

I have a form that my users enter data and I use onFormSubmit to trigger a script that creates a CSV based on the data inserted and after I create the CSV file I delete the data.我有一个用户输入数据的表单,我使用 onFormSubmit 触发一个脚本,该脚本根据插入的数据创建一个 CSV,在我创建 CSV 文件后,我删除了数据。 Problem is that I am deleting the data before creating CSV file.问题是我在创建 CSV 文件之前删除了数据。 Usually I would just make a promise call but I think it is not possible with Google Apps Script.通常我只会做一个承诺电话,但我认为 Google Apps Script 是不可能的。 Is there any alternative to it?有什么替代方法吗?

So my complete code is here:所以我的完整代码在这里:

More insight about what it does: When I receive a new form entry, the "Avaliacao" sheet gets updated and will trigger testTrigger().更深入地了解它的作用:当我收到一个新的表单条目时,“Avaliacao”表会更新并触发 testTrigger()。

Then, it will write the email and the usercity in the LastUser city so it can lookup for some data that I will use to build my CSV file.然后,它将在 LastUser 城市中写入电子邮件和用户城市,以便它可以查找一些我将用于构建 CSV 文件的数据。 But the saveAsCsv function is called before the sheet completed its VLOOKUP calls.但是 saveAsCsv 函数在工作表完成其 VLOOKUP 调用之前被调用。 So my CSV file is empty.所以我的 CSV 文件是空的。

Another issue that I have with synchronization is that if I enable the sLastUser.clear();我在同步方面遇到的另一个问题是,如果我启用sLastUser.clear(); line it will also delete before creating the CSV.在创建 CSV 之前,它还将删除该行。

function testTrigger () {
  //open the sheets
  var SS = SpreadsheetApp.getActiveSpreadsheet();
  var sAvaliacao = SS.getSheetByName("Avaliação");  
  var sPreCSV = SS.getSheetByName("PreCSV");  
  var sInput = SS.getSheetByName("Input");    
  var sLastUser = SS.getSheetByName("LastUser"); 
  var dAvaliacao = sAvaliacao.getDataRange().getValues();
  var dInput = sInput.getDataRange().getValues();

  var avaliacaoLastRow = sAvaliacao.getLastRow()-1;

  var userEmail = dAvaliacao[avaliacaoLastRow][2];
  var userCity = dAvaliacao[avaliacaoLastRow][5];
  var userId = dInput[3][52];

  sLastUser.appendRow([userEmail, userCity]);

  saveAsCSV(userId);
//  sLastUser.clear();   <== this is the line where I can`t enable
}

function saveAsCSV(csvName) {
  // Name
  var fileName = String(csvName) + ".csv"
  // Calls convertcsv
  var csvFile = convertOutputToCsv_(fileName);
  // create the file on my drive
  DriveApp.createFile(fileName, csvFile);
}

function convertOutputToCsv_(csvFileName) {
  // open sheets
  var sPreCSV = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("PreCSV");
  var cont = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Input").getDataRange().getValues()[3][50] + 1;

  var ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("PreCSV").getRange(1, 1, cont, 3);
  try {
    var data = ws.getValues();
    var csvFile = undefined;

    // Loop through the data in the range and build a string with the CSV data
    if (data.length > 1) {
      var csv = "";
      for (var row = 0; row < data.length; row++) {
        for (var col = 0; col < data[row].length; col++) {
          if (data[row][col].toString().indexOf(",") != -1) {
            data[row][col] = "\"" + data[row][col] + "\"";
          }
        }

        // Join each row's columns
        // Add a carriage return to end of each row, except for the last one
        if (row < data.length-1) {
          csv += data[row].join(",") + "\r\n";
        }
        else {
          csv += data[row];
        }
      }
      csvFile = csv;
    }
    return csvFile;
  }
  catch(err) {
    Logger.log(err);
    Browser.msgBox(err);
  }
}

Indeed, the JS engine used by Google Apps Script does not support promises ( Logger.log(Promise); shows it's undefined).实际上,Google Apps Script 使用的 JS 引擎不支持承诺( Logger.log(Promise);显示它是未定义的)。

To make sure that spreadsheet changes take effect before proceeding further, you can use SpreadsheetApp.flush() .为了确保电子表格更改在继续之前生效,您可以使用SpreadsheetApp.flush()

Another relevant feature is event object passed by the trigger on Form Submit: it delivers the submitted data to the script without it having to fish it out of the spreadsheet.另一个相关的功能是通过 Form Submit 上的触发器传递的事件对象:它将提交的数据传递给脚本,而不必将其从电子表格中取出。

现在使用引擎 v8 Promise 是定义对象

There are no native Promises in GAS. GAS 中没有原生 Promise。 With that said you can write your code in ES6/ESnext and make use of promises that way.话虽如此,您可以在 ES6/ESnext 中编写代码并以这种方式使用 promise。 To see how you can configure modules to expose the to the global scope see my comment here .要了解如何配置模块暴露在全球范围内看到我的评论在这里

By doing this you can take advantage of promises.通过这样做,您可以利用承诺。 With that said depending on the size of your project this may be overkill.话虽如此,根据您的项目规模,这可能有点矫枉过正。 In such a case I'd advise using simple callbacks if possible.在这种情况下,我建议尽可能使用简单的回调。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM