Почему при втором запуске функции для l oop возвращается пустая строка? - PullRequest
1 голос
/ 13 апреля 2020

Я пытаюсь разобрать текст, чтобы извлечь только списки имен пользователей между точками с запятой. Ниже приведены журналы и код.

Соответствующий код на стороне сервера:

    function getChats(position,row){
        var sheet = SpreadsheetApp.openById("1pIC6Lyx4Q0ZjEA5GURZ3gA5qLmUJ0_7yGPJQmr6-GnQ");
        var subsheet = sheet.getSheetByName("Accounts");
        var row3 = Number(row);
        var row2 = parseInt(row3);
        var row = String(row2);
        var range = ('S' + row);
        var value = subsheet.getRange(range).getValue();
        Logger.log(value + ", " + row);
        Logger.log(position + ", " + (position - 1));
        var pos1 = value.indexOf(";",position - 1);
        var pos2 = value.indexOf(";",position);
        var content = value.slice(pos1 + 1,pos2);
        Logger.log(pos1 + " " + pos2 + " " + content);
        return content;
    }

Соответствующий код на стороне клиента:

function repeater(openChats){
        alert("Open Chats: " + openChats);
        for (i = 1; i <= Number(openChats); i++){
            alert("Repetition: " + i);

            google.script.run
              .withSuccessHandler(displayChatOptions)
              .getChats(i*2,sessionStorage.getItem('row'));

            //API call above is supposed to run for ever for-loop iteration.

        }
        if (Number(openChats) >= 10){
            var link = document.createElement("BUTTON");
            link.id = "newChatOption";
            link.innerHTML = "Chat Limit Reached";
            link.onclick = "alert('There is currently a limit of 10 chats per Echo Account due to how we handle you data. Updates in the future will enable unlimited chats per Echo Account.')";
            link.className = 'button';
            document.getElementById("sidenav").appendChild(link);
        }
        else{
            var link = document.createElement("BUTTON");
            link.id = "newChatOption";
            link.innerHTML = "Create New Chat";
            link.onclick = 'newChat()';
            link.className = 'button';
            document.getElementById("sidenav").appendChild(link);
            document.getElementById("sidenav").appendChild(document.createElement("BR"));
        }
        chats = openChats;
  }

Журналы: Logs

По какой-то причине, когда функция вызывается со стороны клиента во второй раз, она возвращает пустой текст вместо второго набора имен. Как я могу это исправить? Первый раз, когда я вызываю функцию из for-l oop на стороне клиента, она возвращает то, что я хочу, и работает правильно. Однако во второй раз, когда я запускаю функцию, она возвращает "" (пустая строка).

1 Ответ

2 голосов
/ 13 апреля 2020

Цитата из документации:

API google.script.run позволяет осуществлять 10 одновременных вызовов функций сервера.

google.script.run

У вас есть google.script.run звонок в for l oop. Последующие google.script.run вызовы в for l oop не ждут завершения предыдущего вызова, прежде чем сделать еще один вызов на сервер. Это приводит к нескольким одновременным вызовам одной и той же серверной функции.

Что происходит, так это то, что ваш код на стороне клиента работает быстрее, чем код сервера скриптов Google Apps, поэтому до того, как функция сервера getChats завершено, он вызывается снова. И когда это происходит, предыдущие значения переменных перезаписываются.

Серверная функция getChats(position,row) не выполняет отдельные отдельные экземпляры функции. Перед завершением первого запуска экземпляра функция вызывается снова. Вы пытаетесь одновременно запустить несколько экземпляров одной и той же функции.

Как указано в цитате документации, одновременно может быть только 10 одновременных вызовов к серверу. Если бы вы вызывали 10 разных имен функций, то это было бы по-другому. Все 10 функций с разными именами будут работать независимо. Но создание множества идентичных функций с разными именами не является хорошим решением.

Вы можете использовать LockService.

Цитата из документации:

Предотвращает одновременный доступ к разделам кода. Это может быть полезно, когда несколько пользователей или процессов изменяют общий ресурс и хотят предотвратить конфликты.

Но в зависимости от того, сколько раз вызывается google.script.run и как долго выполняется код, вы может столкнуться с ограничением квоты. Существуют краткосрочные и долгосрочные ограничения. Даже если код находится под долгосрочным лимитом, вы можете легко достичь краткосрочных лимитов из-за многократного вызова SpreadsheetApp.openById.

Итак, что вам следует делать? Вы можете передавать все данные в серверную функцию сразу, а не по одному разу для каждого l oop.

var arrayToSendToServer = [];

for (i = 1; i <= Number(openChats); i++){
    console.log("Repetition: " + i);
    arrayToSendToServer.push(sessionStorage.getItem('row'));
}

google.script.run
  .withSuccessHandler(displayChatOptions)
  .getChats(arrayToSendToServer);

Затем получить электронную таблицу только один раз и l oop через массив, компилируя данные отправить обратно. Затем отправьте скомпилированные данные обратно.

Это всего лишь пример. Я уверен, что в нем есть ошибки. Это просто для того, чтобы дать вам представление о том, что делать.

function getChats(arrayOfData){
  var content,pos1,pos2,range,value;

  var dataToSendBack = [];

    var sheet = SpreadsheetApp.openById("ABC_123");
    var subsheet = sheet.getSheetByName("Accounts");

    L = arrayOfData.length;

    for (i=0;i<L;i++) {
      range = ('S' + i.toString());
      value = subsheet.getRange(range).getValue();

      Logger.log(value + ", " + row);
      Logger.log(position + ", " + (position - 1));

      pos1 = value.indexOf(";",position - 1);
      pos2 = value.indexOf(";",position);
      content = value.slice(pos1 + 1,pos2);

      Logger.log(pos1 + " " + pos2 + " " + content);

      dataToSendBack.push(content);
  }

  return dataToSendBack;
}
...