• 如何解决页面下拉滚动加载数据重复的问题
  • 发布于 2个月前
  • 228 热度
    0 评论
在移动端,页面滚动到底部的时候,都会去加载下一页的数据。这个时候,可能会存在这样的情况,在某处(如:后台管理系统)加载的数据列表中,新增了一条数据,此时,移动端中,获取到下一页的数据,就会和上一页中最后一条数据产生重复,这是用户不希望看到的。那么在前端,就需要把相同的数据过滤掉,怎么优雅的过滤,就是我下面要分享的内容。

一般做法:两个for循环,直接遍历,去掉两个数组中一方相同的数据,再合并即可。此时也会存在一个坑,这个坑在 发布订阅模式那讲中也提到过,就是循环删除数组数据的时候,需要反向遍历数组数据。这个方法确实可以解决上面的遇到的问题,但是还有可优化的地方。

优雅的做法:先考虑一下,加载下一页数据的时候,相同数据可能存在的位置。假设,每次取10条数据,当后台新增了1-10条数据的时候,下一页,相同的数据,都集中在数组的前部。当后台新增了10-19条数据的时候,下一页,相同的数据,就都集中在数组的后部。当后台新增了20以上数据的时候,以后的某一页就会存在第一种情况和第二种情况。

那有没有可能存在只有中间部分相同的数据呢?存在的,就是后台正好把第一页中的数据删除了如头尾几条,又新增了好几条数据,就有可能存在。如果这样的话,就只能使用第一种方法了,双重for循环全部遍历一遍。这种情况的很少会遇到,当然如果你也想把这种情况考虑进去的话,那么上面1,2,3,这三种情况就无法优雅的解决了,而且,随着下滑次数越来越多,数据也会原来越多,遍历的也会更加的多,这也是我们不希望看见的。

下面是实现的代码:
/**
   * 堆代码 duidaima.com
   * originList数组中追加newList数组
   * @param {Object} originList 原数组
   * @param {Object} newList 需要添加的数组
   * @param {Object} id 判断的值
   * 数组去重方法
   */
handleRemoveRepeat(originList, newList, id) {
    if (originList.length === 0 || newList.length === 0) return;

    let tag = 2; /* 0:不反转,1:反转 , 2:直接返回(证明没有重复的数据)*/
    for (let i = 0; i < originList.length; i++) {
        /* 判断第一条数据是否在原有数组中,需要标记,不反转新数组 */
        if (newList[0][id] === originList[i][id]) {
            tag = 0;
            break;
        }
        /* 判断最后一条数据是否在数组中 需要标记,反转新数组,最后还需要反转回来*/
        if (newList[newList.length - 1][id] === originList[i][id]) {
            tag = 1;
            break;
        }
    }
    if (tag === 2) return;
    if (tag === 1) newList.reverse();

    for (let i = 0; i < newList.length; i++) {
        let originListLength = originList.length;
        while (originListLength--) {
            /* 删除相同的数据 */
            if (newList[i][id] === originList[originListLength][id]) {
                originList.splice(originListLength, 1);
                break;
            }
        }
        // 如果存在有数据不重复直接就退出遍历
        if (originListLength + 1 === 0 && newList[i][id] !== originList[originListLength + 1][id]) return;
    }
    if (tag === 1) newList.reverse();
}
解释两处地方:
tag标记的作用:
1. tag=0 ,不反转originList数组
2. tag=1 ,反转originList数组

3. tag=2 ,没有重复数据,直接返回(不考虑中间有相同数据的情况)


newList数组为何需要反转,而后再次反转:
当后台新增了10-19条数据的时候,下一页,相同的数据,就都集中在数组的后部,那么需要从后面进行遍历,这样遍历的次数就会减少。记得最后还需要反转回来,因为最终originList和newList数组需要合并的。(还有一个原因是,代码中的判断是 存在有数据不重复直接就退出遍历).

这里的数组是引用赋值,就不需要再强调了吧。
用户评论