如何在Dart中使用Google Calendar API批量插入事件列表?
问题描述
作为开发者,我需要通过单次调用向Google Calendar中插入事件列表。
为什么选择批量操作?
批量操作可以减少网络开销,提升性能。
当前情况
使用googleapis包时,我仅能执行单次插入操作,代码片段如下:
var eventResponse = await _calendarApi.events .insert(event, calendarId, sendUpdates: 'all');
从开发角度而言,多次调用该方法的效率很低。此外,将insert方法封装为Future组成数组后使用Future.wait()等待所有插入调用执行的方案也并不合理,代码片段如下:
Future<List<Event>> insertEvents(List<Event> events) async { var _calendarApi = CalendarApi(_authClient); List<Future<Event>> _futureEvents = []; for (int i = 0; i < events.length; i++) { _futureEvents.add(_calendarApi.events.insert(events[i], calendarId)); } var _eventResponse = await Future.wait(_futureEvents).catchError((e) => print(e)); return _eventResponse; }
根据Google官方说明,Dart目前没有原生支持的批量操作方案。请问是否有更优的可行性解决方案?
解决方案
方案1:使用googleapis内置BatchRequest实现单次网络调用批量插入
googleapis包本身内置了符合Google API规范的HTTP批量请求能力,无需多次发起网络请求即可完成多个事件插入,是当前最优方案,实现代码如下:
import 'package:googleapis/calendar/v3.dart'; Future<List<Event>> batchInsertEvents(List<Event> events, String calendarId, AuthClient client) async { final calendarApi = CalendarApi(client); final batch = BatchRequest(); final List<Event> successEvents = []; final List<Object> errorList = []; for (final event in events) { calendarApi.events.insert(event, calendarId, sendUpdates: 'all') ..then((resp) => successEvents.add(resp)) ..catchError((e) => errorList.add(e)); } // 执行批量请求,仅发起一次网络调用 await batch.send(client); // 可根据业务需求处理错误,比如全部成功才返回、部分失败提示用户等 if (errorList.isNotEmpty) { throw Exception("批量插入失败,共${errorList.length}条事件插入异常"); } return successEvents; }
注意:Google Calendar API单次批量请求最多支持100个子请求,超出数量可拆分多批执行。
方案2:优化并发控制适配小批量场景
如果你的单次插入量不超过20条,也可以在原有Future.wait方案基础上增加并发数限制,避免触发Google API限流规则,实现成本更低:
Future<List<Event>> insertEventsWithLimit(List<Event> events, String calendarId, AuthClient client, {int maxConcurrency = 5}) async { final calendarApi = CalendarApi(client); final result = <Event>[]; // 按最大并发数拆分请求块 for (var i = 0; i < events.length; i += maxConcurrency) { final end = i + maxConcurrency > events.length ? events.length : i + maxConcurrency; final chunk = events.sublist(i, end); final chunkFutures = chunk.map((e) => calendarApi.events.insert(e, calendarId)).toList(); final chunkRes = await Future.wait(chunkFutures); result.addAll(chunkRes); // 可按需增加请求间隔降低限流风险 await Future.delayed(const Duration(milliseconds: 100)); } return result; }
内容的提问来源于stack exchange,提问作者Zujaj Misbah Khan
相关产品推荐
相关产品推荐

