Ошибка тайм-аута скрипта листа Google - PullRequest
0 голосов
/ 30 июня 2018

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

У меня есть этот кусок кода онлайн, который работает довольно хорошо. Однако проблема в том, что сценарий всегда будет зависать, пока не завершится получение всех изображений.

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

Спасибо

Вот код, который у меня есть

function listFilesInFolder(folderName) {

   var sheet = SpreadsheetApp.getActiveSheet();
   sheet.appendRow(["Name", "File-Id"]);


//change the folder ID below to reflect your folder's ID (look in the URL when you're in your folder)
    var folder = DriveApp.getFolderById("ID");
    var contents = folder.getFiles();

    var cnt = 0;
    var file;

    while (contents.hasNext()) {
        var file = contents.next();
        cnt++;
            data = [
                file.getName(),
                file.getId(),
            ];
            sheet.appendRow(data);
    };
};

Ответы [ 2 ]

0 голосов
/ 01 июля 2018

Попробуйте добавить это: if (cnt% 500 === 0) {SpreadsheetApp.flush ();}

function listFilesInFolder(folderName) {

   var sheet = SpreadsheetApp.getActiveSheet();
   sheet.appendRow(["Name", "File-Id"]);


//change the folder ID below to reflect your folder's ID (look in the URL when you're in your folder)
    var folder = DriveApp.getFolderById("ID");
    var contents = folder.getFiles();

    var cnt = 0;
    var file;

    while (contents.hasNext()) {
        var file = contents.next();
        cnt++;
            data = [
                file.getName(),
                file.getId(),
            ];
            sheet.appendRow(data);
            if (cnt % 500 ===0){
              SpreadsheetApp.flush();
            }

    };
};

Я заметил много проблем при работе с большими таблицами. Я сейчас работаю над проектом в Google и слышу, как они переписывают способ работы интерпретатора / компилятора.

0 голосов
/ 30 июня 2018

Когда я увидел твой вопрос, я изобразил 2 образца. Но я думаю, что есть несколько ответов для вашей ситуации. Поэтому, пожалуйста, подумайте об этом как о двух из них.

Шаблон 1:

  • Используйте setValues() вместо appendRow().
    • Данные создаются в цикле while. И поместите данные в электронную таблицу, используя setValues().

Модифицированный скрипт:

function listFilesInFolder(folderName) {
  var data = [["Name", "File-Id"]];
  var folder = DriveApp.getFolderById("ID"); // Please set this.
  var contents = folder.getFiles();
  while (contents.hasNext()) {
    var file = contents.next();
    data.push([file.getName(), file.getId()]);
  };
  var sheet = SpreadsheetApp.getActiveSheet();
  sheet.getRange(sheet.getLastRow() + 1, 1, data.length, data[0].length).setValues(data); // Modified
};

Шаблон 2:

  • Использовать Drive API.
    • Получить данные с помощью Drive API. И поместите данные в электронную таблицу, используя setValues().

Чтобы использовать этот пример сценария, включите Drive API в Advanced Services и консоли API. Вы можете увидеть поток этого в здесь .

Модифицированный скрипт:

function listFilesInFolder2(folderName) {
  var folderId = "ID"; // Please set this.
  var data = [["Name", "File-Id"]];
  var params = {
    'pageSize': 1000,
    'q': "'" + folderId + "' in parents and mimeType!='" + MimeType.FOLDER + "'",
    'fields': "nextPageToken,items(id,title)"
  };
  do {
    var r = Drive.Files.list(params);
    params["pageToken"] = r.nextPageToken;
    r.items.forEach(function(e) {data.push([e.title, e.id])});
  } while(r.nextPageToken);
  var sheet = SpreadsheetApp.getActiveSheet();
  sheet.getRange(sheet.getLastRow() + 1, 1, data.length, data[0].length).setValues(data); // Modified
};

Рекомендации:

Если это не то, что вы хотите, извините.

Добавлено:

В комментарии @ Steve Gon why do you think SetValue is better than AppendRow? я добавил причину, по которой я предлагаю setValues() вместо appendRow().

В этом случае, когда многие файлы (более 3000) в папке извлекаются и помещаются в электронную таблицу, время обработки составляет более 6 минут, что является ограничением. Если мое понимание верно, я думаю, что ОП хочет решить эту проблему. Хотя я предлагаю использовать «setValues ​​()», потому что я знал, что значения 10000 строк с 2 столбцами могут быть помещены на лист без ошибок, используя его, я не показал разницу времени процесса в своем ответе. Мне очень жаль это Поэтому я добавил это.

Я подготовил 2 примера сценария для этой ситуации. Основная работа состоит в том, чтобы поместить 10 000 строк с 2 столбцами на лист. Это больше, чем 3000 вопроса. В это время он измеряет время обработки setValues() и appendRow().

Пример сценария с использованием setValues ​​()

var label = "sampleLabel"
console.time(label);
var rows = 10000;
var values = [];
for (var i = 0; i < rows; i++){
  values.push(["Name", "File-Id"]);
}
var ss = SpreadsheetApp.getActiveSheet();
ss.getRange(ss.getLastRow() + 1, 1, values.length, values[0].length).setValues(values);
console.timeEnd(label);

Пример сценария с использованием appendRow ()

var label = "sampleLabel"
console.time(label);
var rows = 10000;
var ss = SpreadsheetApp.getActiveSheet();
for (var i = 0; i < rows; i++){
  ss.appendRow(["Name", "File-Id"]);
}
console.timeEnd(label);

Результат:

  • При использовании setValues() время процесса составляло 2 с - 3 с. И ошибок нет.
  • Когда использовалось appendRow(), когда значение было установлено в 1400 - 1500 строк, время выполнения превышало 6 минут. Хотя я пробовал несколько раз, 3000 строк не могли быть помещены.

Вот почему я предложил setValues().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...