从对象数组创建Set仍存重复项,WordPress API回调问题求助
嘿,我之前做WordPress项目时也碰到过类似的API分页重复问题,给你梳理几个排查方向和实用解决方案:
先搞清楚重复项的根源
首先得定位重复是怎么来的,大概率是这几个原因:
- 分页参数没控制好:WP API默认用
page参数分页,如果你的循环终止条件写得有问题(比如多跑了一次相同的page),就会拉到重复内容。比如你知道总共有40篇唯一文章,当数组长度接近40时,可能最后一次请求的还是之前的页码。 - 对象引用导致Set失效:你说用Set去重没用?那大概率是你存的是文章对象——Set是按引用比较的,哪怕两个对象内容完全一样,只要是不同的引用,Set就会当成不同项,自然去不掉重复。
- 异步回调的竞态问题:如果是用异步请求(比如
fetch/axios),可能存在前一次回调还没完成,后一次请求已经发起的情况,但你说只有最后一次重复,这个可能性相对低一些。
针对性解决方案
1. 从源头避免重复请求(最推荐)
先确保不会重复请求同一页,调整分页逻辑:
let currentPage = 1; const perPage = 10; const targetTotal = 40; // 已知的唯一文章总数 let allPosts = []; function fetchCategoryPosts() { // 替换成你的分类ID和API地址 fetch(`/wp-json/wp/v2/posts?categories=你的分类ID&page=${currentPage}&per_page=${perPage}`) .then(res => res.json()) .then(posts => { // 先把当前页的文章加进去 allPosts.push(...posts); // 终止条件:要么返回的文章数不足perPage(说明到最后一页了),要么总数达到目标 if (posts.length === perPage && allPosts.length < targetTotal) { currentPage++; fetchCategoryPosts(); } else { // 到这里数组应该就没有重复了 console.log("最终去重后数组长度:", allPosts.length); // 处理后续流程 } }) .catch(err => console.error("API请求出错:", err)); } fetchCategoryPosts();
如果不确定目标总数,可以先请求分类的统计数据:/wp-json/wp/v2/categories/你的分类ID,拿到count字段后再计算总页数,避免瞎循环。
2. 万一还是有重复,用唯一ID去重(针对对象数组)
既然Set对对象无效,就用文章的唯一ID(post.id)来处理,这是最靠谱的方式:
// 方法1:用Map做映射,保留每个ID的第一个实例 const uniquePosts = Array.from( allPosts.reduce((postMap, post) => { if (!postMap.has(post.id)) { postMap.set(post.id, post); } return postMap; }, new Map()) ).map(item => item[1]); // 方法2:用Set记录已出现的ID,过滤数组 const seenIds = new Set(); const uniquePosts = allPosts.filter(post => { if (seenIds.has(post.id)) return false; seenIds.add(post.id); return true; });
这两种方法都能确保每个ID只保留一篇文章,完美解决对象引用导致的去重失效问题。
3. 快速排查小技巧
每次请求后,打印当前页码和返回的文章ID列表:
console.log(`当前请求页码:${currentPage},返回的文章ID:`, posts.map(p => p.id));
这样一眼就能看出最后一次请求的ID是不是之前已经出现过,快速定位是请求重复还是API本身返回重复。
总结
先从分页逻辑入手,确保不会多请求一次重复页码;如果还是有漏网的重复项,就用文章ID去重,别直接用Set处理对象。我之前就是因为循环终止条件写错,多跑了一次最后一页,调整后就解决了,你可以先试试打印页码和ID列表,很快就能找到问题所在。
内容的提问来源于stack exchange,提问作者synj
相关产品推荐
相关产品推荐

