分页加载时怎么避免重复请求和数据错乱?

晓萌 Dev 阅读 40

我用 Vue 做了个列表,滚动到底部就加载下一页,但有时候快速滚动会触发多次请求,导致数据重复或者顺序错乱。试过加 loading 锁,但好像没完全解决问题。

这是我的加载逻辑:

<template>
  <div @scroll="handleScroll" style="height: 400px; overflow-y: auto">
    <div v-for="item in list" :key="item.id">{{ item.name }}</div>
  </div>
</template>

<script>
export default {
  methods: {
    async handleScroll() {
      if (this.loading) return;
      this.loading = true;
      const res = await fetch(/api/items?page=${this.page++});
      this.list.push(...res.data);
      this.loading = false;
    }
  }
}
</script>
我来解答 赞 8 收藏
二维码
手机扫码查看
2 条解答
春艳
春艳 Lv1
看起来你在处理滚动加载时遇到了常见的竞态条件问题。loading锁确实是个好的开始,但还不够完善。我建议加个防抖处理,并且在请求返回前不允许触发新的请求。

首先,把 loading 变量改成更清晰的状态机,比如 idle/loading/completed/error。然后用防抖来限制频繁触发。

另外,你可能需要检查当前页数和总页数,避免重复请求已经获取过的数据。

这里给你改进后的代码逻辑:


data() {
return {
status: 'idle',
page: 1,
totalPages: null
};
},
methods: {
handleScroll: _.debounce(async function() {
if (this.status !== 'idle' ||
this.page > this.totalPages) return;

this.status = 'loading';
try {
const res = await fetch(/api/items?page=${this.page});
this.list.push(...res.data);
this.totalPages = res.totalPages;
this.page++;
this.status = 'idle';
} catch {
this.status = 'error';
}
}, 300)
}


这个版本加入了状态管理和防抖,调试看看应该能解决你的问题。记得测试快速滚动的情况。这种异步操作的场景最容易出问题,多测几个边界情况总是好的。
点赞
2026-03-30 15:04
FSD-菲菲
你这个情况我遇到过,确实挺烦人的。除了加loading锁,还需要做几个关键处理:

1. 加个防抖,避免滚动事件触发太频繁:
export default {
data() {
return {
debounceTimer: null,
// 其他数据...
}
},
methods: {
async handleScroll() {
clearTimeout(this.debounceTimer)
this.debounceTimer = setTimeout(() => {
if (this.loading) return
// 其他逻辑...
}, 300) // 300ms防抖
}
}
}


2. 要做页码校验,防止并发请求导致page自增混乱:
const currentPage = this.page
const res = await fetch(/api/items?page=${currentPage})
// 检查返回数据是否确实是对应页码的
if (res.page === currentPage) {
this.page++
this.list.push(...res.data)
}


3. 安全提醒:别忘了加错误处理,网络请求可能会失败。建议把loading状态放在finally里:
try {
this.loading = true
// 请求逻辑...
} catch (e) {
console.error('加载失败', e)
// 可以在这里回退page计数
} finally {
this.loading = false
}


另外建议用IntersectionObserver替代scroll事件监听,性能更好也更精确。不过要看你项目浏览器兼容性要求。
点赞 1
2026-03-05 19:07