You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用Google Calendar API获取事件每次返回数量不一致问题

问题原因
  • 异步并发请求的完成判断逻辑错误
    你在for循环中同步发起了所有日历的事件拉取请求,getEvents是异步接口,各请求的返回顺序完全不固定。你当前触发addInvoices的条件是i == data.items.length -1,仅判断「最后一个发起的请求是否返回」,而非「所有发起的请求全部返回」。比如你有5个日历,编号0-4,可能编号4的请求最先返回,此时你就直接执行了addInvoices,但前4个请求还没返回,Invoices数组里只有第4个日历的事件,就会出现事件数量偏少的情况;如果某次4号请求刚好是最后一个返回的,就能拿到所有数据,这是每次事件数量不一致的核心原因。
  • 全局数组未做初始化重置
    从代码逻辑推断Invoices是全局变量,如果每次执行execute方法前没有清空该数组,上次执行残留的事件数据会累积到本次结果中,也会导致每次统计的数量出现偏差。
  • 对象去重逻辑无效
    你使用!Invoices.includes(events[m])做事件去重,但includes对引用类型的判断是对比内存地址,即使两个事件是完全相同的跨日历共享事件,只要是不同请求返回的就会被判定为不同对象,该去重逻辑完全不生效,也可能导致重复数据被推入数组造成数量异常。
修复方案

使用Promise.all统一管理所有异步请求,同时修正去重逻辑、增加全局数组初始化步骤,参考改造后代码:

// Make sure the client is loaded and sign-in is complete before calling this method.
function execute() {
  // 每次执行前清空全局数组,避免旧数据累积
  Invoices = [];
  return gapi.client.calendar.calendarList.list({})
      .then(async function(response) {
              let data = JSON.parse(response.body);
              // 收集所有事件请求的Promise实例
              const eventReqList = data.items.map(calendarItem => getEvents(calendarItem.id));
              // 等待所有请求全部完成后再执行后续逻辑
              await Promise.all(eventReqList);
              addInvoices(Invoices);
              console.log(Invoices);
            },
            function(err) { console.error("Execute error", err); });
}


function getEvents(calendar_id) {
        let start_date = new Date($('#start_date').val());
        let end_date = new Date($('#end_date').val());
  return gapi.client.calendar.events.list({
               'calendarId': calendar_id,
               'timeMax': end_date.toISOString(),
               'timeMin': start_date.toISOString(),
               'showDeleted': false,
               'singleEvents': true,
               'orderBy': 'startTime'
       })
              .then(function(response) {
          let events = response.result.items;
          // 用事件唯一ID做去重判断,替代引用对比
          const existEventIds = Invoices.map(item => item.id);
          for(let m = 0; m < events.length; m++) {
                  if(!existEventIds.includes(events[m].id)) {
                          Invoices.push(events[m]);
                  }
          }
          return events;
         },
         function(err) { console.error("Execute error", err);});
}

gapi.load("client:auth2", function() {
  gapi.auth2.init({client_id: "{{ $currentCompany->getSetting('client_id') ? $currentCompany->getSetting('client_id') : '' }}"});
});

内容的提问来源于stack exchange,提问作者Urban Design

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 15:09:03