简体   繁体   English

减少 Google Apps 脚本中的脚本运行时间?

[英]Reduce script run time in Google Apps Script?

I created a script that tracks attendance for distance learning.我创建了一个脚本来跟踪远程学习的出勤情况。 After a while it times out so I think I am having issues with too many calls to the Google Classroom API, however I don't see a way that I can change it to take those calls out of a loop.过了一会儿,它超时了,所以我认为我对 Google Classroom API 的调用过多有问题,但是我没有看到可以更改它以将这些调用排除在循环之外的方法。

The script takes all the Google Classroom classes that my apps script account is a co-teacher on and using timed triggers creates a daily attendance assignment with one question that says 'here'.该脚本采用我的应用程序脚本帐户作为助理教师的所有 Google 课堂课程,并使用定时触发器创建每日出勤作业,其中有一个问题,上面写着“这里”。 Students are then supposed to answer the question and then another trigger at night runs the function to 'grade' each assignment and populate my spreadsheet so school secretaries can view it in the morning and record the previous days attendance.然后学生应该回答问题,然后另一个触发器在晚上运行该功能以“评分”每项作业并填充我的电子表格,以便学校秘书可以在早上查看并记录前几天的出勤率。

The part that seems to have the bottleneck is my getStudentResponses() function.似乎有瓶颈的部分是我的 getStudentResponses() 函数。 I tried to reduce time by filtering out students that didn't submit the assignment, but it wasn't enough.我试图通过过滤掉没有提交作业的学生来减少时间,但这还不够。 Does anyone see any way that I can make this faster?有没有人看到我可以加快速度的任何方法? I was reading up on using the Cache Service, but I couldn't figure out how to get that to work.我正在阅读有关使用缓存服务的信息,但我不知道如何让它工作。 Any help would be appreciated.任何帮助,将不胜感激。

var ss = SpreadsheetApp.getActive();
var date = new Date();

/*
creates a button to programmatically create all necessary timed triggers for easy deployment
*/
function onOpen() {
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('Attendance')
      .addItem('Create Triggers', 'createTriggers')
      .addToUi();
}

/*
auto accepts any co-teacher invites
*/
function acceptInvite() {
  try{
    var optionalArgs = {
      userId: "me"
    };
    var invites = Classroom.Invitations.list(optionalArgs);
    for(var i = 0; i < invites.invitations.length; i++) {
      Classroom.Invitations.accept(invites.invitations[i].id);
    }
  }
  catch(e){}
}

/*
populates a spreadsheet with all the classes that the script Google account is a co-teacher of
the sheet has two columns one with the course name and two with the course id
*/
function listCourses() {
  var optionalArgs = {courseStates: "ACTIVE"};
  var response = Classroom.Courses.list(optionalArgs);
  var courses = response.courses;
  var classSheet;
  
  try{
    classSheet = ss.insertSheet("Classes", 0);
    ss.insertSheet("Assignments", 1);
  }
  catch(e) {
    classSheet = ss.getSheetByName("Classes");
  }
  classSheet.clear();
  if (courses && courses.length > 0) {
    for (i = 0; i < courses.length; i++) {
      var course = courses[i];
      classSheet.appendRow([course.name, course.id]);
    }
  }
}

/*
reads the sheet to get all the classes and creates a new array with all the class IDs
*/
function getCourses() {
  var classSheet = ss.getSheetByName("Classes");
  var classList = new Array();
  var range = classSheet.getDataRange();
  var values = range.getValues();
  
  for(var i in values) {
    var row = values[i];
    var courseId = row[1]+"";
    classList.push(Classroom.Courses.get(courseId));
  }
  createTopics(classList);
}

/*
called immediatly after getCourses, creates topics in each class that will contain the daily attendance assignment
*/
function createTopics(classList) {
  for(i = 0; i < classList.length; i++) {
    var topic;
    var resource = {name: "Daily Online Attendance"};
    
    try {
      topic = Classroom.Courses.Topics.create(resource, classList[i].id);
      createAssignment(topic,classList[i]);
    }
    catch(e) {
      if(e == "GoogleJsonResponseException: API call to classroom.courses.topics.create failed with error: Requested entity already exists") {
        var topics = Classroom.Courses.Topics.list(classList[i].id);

        for(j = 0; j < topics.topic.length; j++) {
          if(topics.topic[j].name == "Daily Online Attendance") {
            createAssignment(topics.topic[j], classList[i]);
          }
        }
      }
    }
  }
}

/*
creates an assignment in each class, under each topic
each assignment only has one choice that says "here" and is going to be 'graded' each night to track attendance
*/
function createAssignment(topic,course) {
  var resource = {
    title: "Attendance for "+(date.getMonth()+1)+"/"+date.getDate()+"/2020",
    description: "Please fill this assignment out each day for attendance",
    topicId: topic.topicId,
    state: "PUBLISHED",
    workType: "MULTIPLE_CHOICE_QUESTION",
    multipleChoiceQuestion: {
      "choices": [
        "Here"
      ] 
    }
  };
  try {
    var assignment = Classroom.Courses.CourseWork.create(resource, course.id);
    var sheet = ss.getSheetByName("Assignments");
    sheet.appendRow([course.id,assignment.id]);
  }
  catch(e){}
}

/*
creates a new sheet for each day and logs each assignement
*/
function getStudentResponses() {
  var assignmentSheet = ss.getSheetByName("Assignments");
  var sheet2;
  var response;

  assignmentSheet.sort(1, true);
  
  try{
    sheet2 = ss.insertSheet("Attendance for "+(date.getMonth()+1)+"/"+date.getDate()+"/2020",(ss.getSheets().length-(ss.getSheets().length-2)));
    sheet2.appendRow(["Student Last Name","Student First Name","Grade","Class Name","Assignment Answer"]);
  }
  catch(e) {
    sheet2 = ss.getSheetByName("Attendance for "+(date.getMonth()+1)+"/"+date.getDate()+"/2020");
  }
  
  sheet2.setFrozenRows(1);
  
  var range = assignmentSheet.getDataRange();
  var values = range.getValues();
  
  for(var i in values) {
    var row = values[i];
    var courseId = row[0]+"";
    var courseWorkId = row[1]+"";
    
    try {
      response = Classroom.Courses.CourseWork.StudentSubmissions.list(courseId, courseWorkId);
        
      for(var j in response.studentSubmissions) {
        if(response.studentSubmissions[j].state == "TURNED_IN") {
          try {
            var grade;
            var email = Classroom.UserProfiles.get(response.studentSubmissions[j].userId).emailAddress;
            sheet2.appendRow([Classroom.UserProfiles.get(response.studentSubmissions[j].userId).name.familyName,Classroom.UserProfiles.get(response.studentSubmissions[j].userId).name.givenName,grade,Classroom.Courses.get(courseId).name,response.studentSubmissions[j].multipleChoiceSubmission.answer]);
          }
          catch (e) {}
        }
      }
    }
    catch(e) {}
  }
}

/*
deletes all assignemnts that were created
*/
function deleteAssignments() {
  var assignmentSheet = ss.getSheetByName("Assignments");
  assignmentSheet.sort(1, true);
  var range = assignmentSheet.getDataRange();
  var values = range.getValues();
  
  for(var i in values) {
    var row = values[i];
    var courseId = row[0]+"";
    var courseWorkId = row[1]+"";
    
    try {
      Classroom.Courses.CourseWork.remove(courseId, courseWorkId);
    }
    catch(e) {}
  assignmentSheet.clear();
  }
}

function createTriggers() {
  ScriptApp.newTrigger('getCourses')
      .timeBased()
      .everyDays(1)
      .atHour(6)
      .create();
  
  ScriptApp.newTrigger('getStudentResponses')
      .timeBased()
      .everyDays(1)
      .atHour(22)
      .create();
  
  ScriptApp.newTrigger('deleteAssignments')
      .timeBased()
      .everyDays(1)
      .atHour(23)
      .create();
  
  ScriptApp.newTrigger('listCourses')
      .timeBased()
      .everyDays(1)
      .atHour(21)
      .create();
  
  ScriptApp.newTrigger('acceptInvite')
      .timeBased()
      .everyDays(1)
      .atHour(20)
      .create();
}

appendRow is slow, you should avoid to used it inside a for loop. appendRow很慢,你应该避免在for循环中使用它。 Instead build an array, then pass the values using a single setValues call.而是构建一个数组,然后使用单个setValues调用传递值。

Resources资源

Related有关的

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

相关问题 如何减少此Google Apps脚本的执行时间? - How to reduce execution time of this Google Apps Script? Google Apps 脚本运行得更快 - Google Apps Script run faster 需要Google Apps脚本中的.makeCopy替代品以减少运行时间 - Need alternative to .makeCopy in Google Apps Script to decrease run time Google Apps 脚本:代码按预期工作,但完成的时间很长。 如何减少脚本时间? - Google Apps Script: The code is working as intended, but the time to complete is quite long. How can I reduce the script time? Google Apps 脚本时间触发器在 50% 的情况下超时,但控制台运行在 100% 的时间内有效 - Google Apps Script Time-Trigger Exceeeded Time in 50% of cases, but Console Run works 100% of time 如何减少此脚本的执行时间(Google应用脚本超时) - How to reduce execution time of this script (Google app script timeout) Google Apps 脚本 - 最长执行时间 - Google Apps Script - MAX EXECUTION TIME 尝试简化多个for循环以减少Google Script中的执行时间 - Trying to streamline multiple for loops to reduce the execution time in Google Script 减少PowerShell脚本的运行时间 - Reduce running time of PowerShell script 缓慢归档 Google Apps 脚本 - Slow Archiving Google Apps Script
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM