调用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
相关产品推荐
相关产品推荐

