如何高效合并Notion、Todoist、DevOps多源任务数组并实现跨平台同步
高效合并实现方案
原方案的时间复杂度为O(NMK)(N为来源数量、M为单来源任务数、K为已合并任务数),核心性能瓶颈是嵌套遍历已合并集合做匹配。优化核心是用哈希表做全局ID索引,将匹配查找复杂度从O(K)降到O(1),最终整体时间复杂度降到O(T)(T为所有来源总任务数)。
实现思路:
- 建立全局索引Map,键为
${平台名}:${平台ID},值为对应合并任务的引用 - 遍历所有任务时先通过索引判断是否存在关联的已合并任务,存在则合并数据,不存在则新增合并任务
- 所有新增的有效平台ID都同步写入索引,保证后续任务可以快速匹配
实现代码示例:
// 全局索引:key 为 `${平台名}:${平台ID}`, value 为合并任务对象引用 const integrationIdIndex = new Map() const merged = [] for (const collection of fetchedTasks) { for (const task of collection) { let existingTask = null // 提取当前任务所有非空的平台ID映射 const validIntegrationEntries = Object.entries(task.integrations) .filter(([_, integrationConfig]) => integrationConfig.id != null) .map(([integrationName, integrationConfig]) => [ `${integrationName}:${integrationConfig.id}`, integrationName, integrationConfig ]) // 查找是否存在关联的已合并任务 for (const [indexKey] of validIntegrationEntries) { if (integrationIdIndex.has(indexKey)) { existingTask = integrationIdIndex.get(indexKey) break } } if (existingTask) { // 合并当前任务的原始数据到已存在的合并任务 for (const [indexKey, integrationName, integrationConfig] of validIntegrationEntries) { // 仅当对应平台没有原始数据时赋值,避免覆盖 if (!existingTask.integrations[integrationName].original) { existingTask.integrations[integrationName].original = integrationConfig.original ?? task } // 新增的平台ID同步写入索引 if (!integrationIdIndex.has(indexKey)) { integrationIdIndex.set(indexKey, existingTask) } } } else { // 新增合并任务 merged.push(task) // 所有有效ID写入索引 for (const [indexKey] of validIntegrationEntries) { integrationIdIndex.set(indexKey, task) } } } }
如果需要处理字段冲突(比如不同来源同一任务的状态、优先级不一致),可以在合并数据的步骤插入自定义冲突解决逻辑,比如取最后更新时间最新的字段值即可。
适用的设计模式
- 防腐层(ACL)模式:你当前做的多平台API数据标准化就是典型的防腐层实现,将外部异构的平台数据转换成内部统一的领域模型,隔离外部平台接口变更对内部逻辑的影响。
- 聚合根模式:把每个跨平台关联的任务作为一个聚合根,所有平台的关联任务都是聚合根下的子实体,统一维护聚合根的状态,避免多平台数据不一致。
- 注册表模式:上述优化方案里的全局ID索引就是注册表模式的实现,用统一的注册表维护所有平台ID和聚合根的映射关系,实现关联任务的快速查找。
- 事件溯源模式:如果后续需要做双向同步(修改合并任务后回写到所有关联平台),可以用事件溯源记录所有对任务的变更操作,异步消费事件同步到对应平台,避免同步调用超时或失败导致的数据不一致。
内容的提问来源于stack exchange,提问作者Hugo
相关产品推荐
相关产品推荐

