前端两次请求接口时,第二次请求返回比第一次请求快,怎么办

以往在业务中请求接口的时候,总是先请求的先返回,请求顺序和返回顺序可以对上,根据数据渲染的页面也就自然没有问题。

但假如有这样一个场景:

一个页面有两个tab,暂且命名为tab1和tab2,tab中是一个表格,我们通过点击tab请求接口获取对应tab中的表格数据,初始时没有选中tab。点击tab1先请求,但是由于接口数据过多,响应较慢,这时用户点击了tab2开始了第二次请求,tab2的请求中接口数据少,响应很迅速,于是在第一次请求还响应的时候,第二次请求已经响应并完成处理。

这个过程中,页面表现为:在tab2中先展示第二次接口返回的表格数据,然后再展示第一次接口请求返回的数据,这就导致了tab2展示的其实是tab1的数据,于是一个bug在某位程序员手中不知不觉的诞生了…

如何解决这一问题呢?

以上场景的问题核心其实是异步请求竞态,也就是两个异步请求的响应顺序与发送顺序不一致,导致后渲染的数据覆盖了先需要的内容。解决这一问题的方法其实也简单,就是忽略过期请求

那么如何忽略过期请求呢,其实就是为每一个请求配一个请求唯一标识,响应时基于这个标识去判断是否为最新请求,如果不是最新请求,就不去采用返回的结果了。

多说无益,上代码

// 标识,用于判断接口响应是否为最新
let requestId = 0;

// 请求
async fetchList () {
	// requestId自加后赋值给currentId 作为当前请求的唯一标识
	const currentId = ++requestId;
	const res = await fetch('/api/list');
	// 响应返回后进行判断,不是最新返回则不采用
	if (currentId !== requestId) {
		return;
	} else {
		// 相等再进行对于res的处理
	}
}

为什么能解决异步请求竞态的问题呢?

假设短时间内连续触发两次 fetchList():

  1. 第一次调用:currentId = 1,requestId 变为 1,发送请求 1。
  2. 第二次调用:currentId = 2,requestId 变为 2,发送请求 2(后发送,可能先响应)。
  3. 若请求 2 先响应:此时 currentId=2 与 requestId=2 相等,正常处理数据。
  4. 若请求 1 后响应:此时 currentId=1 与 requestId=2 不相等,直接忽略,避免旧数据覆盖新数据。

通过这种方式,无论请求响应顺序如何,最终只处理最新一次请求的结果,解决了 “慢请求覆盖快请求” 的竞态问题。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值