长轮询中用ID作key构建新旧Map可高效识别增删改:新增为newMap有而oldMap无的key,删除为oldMap有而newMap无的key,更新需遍历共有key并深比较字段。

在长轮询(Long Polling)场景中,用 Map 对比前后两次响应的数据,高效识别新增和删除的记录,关键在于:用唯一键(如 ID)作为 Map 的 key,把完整对象或必要字段存为 value;通过遍历新旧 Map 的 key 集合做差集运算。
用 ID 作 key 构建前后两个 Map
每次轮询拿到新数据后,不要直接比对原始数组,先统一转成 Map。假设每条记录有 id 字段:
const oldMap = new Map(oldData.map(item => [item.id, item])); const newMap = new Map(newData.map(item => [item.id, item]));
这样后续所有操作都基于 key 的集合运算,时间复杂度为 O(n),远优于嵌套循环的 O(n²)。
找出新增的记录
新增 = 新 Map 中有、旧 Map 中没有的 key。可用 for...of 遍历 newMap.keys(),逐个检查:
立即学习“Java免费学习笔记(深入)”;
- 更简洁的方式是用
Array.from(newMap.keys())转成数组,再用filter:
const addedIds = Array.from(newMap.keys()).filter(id => !oldMap.has(id)); const addedItems = addedIds.map(id => newMap.get(id));
如果只需要 ID 列表,就只保留第一行;如果需要完整对象,再查一次 newMap 即可。
找出被删除的记录
删除 = 旧 Map 中有、新 Map 中没有的 key。逻辑同上,只是调换主从关系:
- 同样用
Array.from(oldMap.keys())过滤:
const removedIds = Array.from(oldMap.keys()).filter(id => !newMap.has(id)); const removedItems = removedIds.map(id => oldMap.get(id));
注意:这里取的是 oldMap.get(id),因为被删的数据只保留在旧快照里。
可选:同时获取更新的记录
如果还需识别“内容变更”的记录(ID 存在但字段不同),可在遍历共有的 key 时深比较:
const updatedItems = [];
for (const id of oldMap.keys()) {
if (newMap.has(id)) {
const oldItem = oldMap.get(id);
const newItem = newMap.get(id);
// 简单判断:JSON.stringify 比较(仅适用于无函数/undefined/Date 等)
if (JSON.stringify(oldItem) !== JSON.stringify(newItem)) {
updatedItems.push({ id, old: oldItem, new: newItem });
}
}
}
生产环境建议用轻量 diff 工具(如 shallowequal 或自定义字段白名单比对),避免序列化开销与陷阱。


















