uni-app 整个应用接口请求阻塞
uni-app 整个应用接口请求阻塞
操作步骤:
- 在一个页面请求接口,这个接口响应时间设置很久。然后退出当前页面。进去其他页面。其他页面的接口请求没有发出
预期结果:
- 每个页面是每个页面的请求。互不影响
实际结果:
- 其中一个页面接口请求较慢会影响其他页面的接口请求无法发出
bug描述:
- 整个应用接口请求阻塞
- 在安卓端,场景:当我进入某个页面,这个页面的接口请求要很久。然后我退出了这个页面,我再进入其他页面,发现其他页面的接口请求都没有执行。只有当之前那个页面的接口请求完成或者进入了请求超时fail了之后,其他页面的接口请求才会发出,这个是为什么呢?
- H5端不会出现这个情况
附件
信息类别 | 详细信息 |
---|---|
产品分类 | uniapp/App |
PC开发环境操作系统 | Windows |
PC开发环境操作系统版本号 | windows 10 |
HBuilderX类型 | 正式 |
HBuilderX版本号 | 4.28 |
手机系统 | Android |
手机系统版本号 | Android 14 |
手机厂商 | vivo |
手机机型 | iQOO Neo9S Pro |
页面类型 | vue |
vue版本 | vue3 |
打包方式 | 云端 |
项目创建方式 | HBuilderX |
App下载地址或H5网址 | https://app.liuyingyong.cn/build/download/dd168b70-8c2e-11ef-b172-bd30c1125d82 |
有官网的人能验证一下吗?还是说我的代码有问题呢?
来个h5网址看看
H5测试是正常的,切换页面后的接口请求正常,安卓app不行
回复 p***@163.com: 抓包看了吗?是一直在请求?是不是有条件编译语句区分的逻辑
你好,根据你的描述模拟了一个场景:在 A 页面点击请求后跳转到 B 页面,A 页面的请求会有延迟 3s 后返回,并且通过拦截器进行一个请求前的提醒,执行结果如下:
点击发起请求后,立刻跳转到 B 页面,B 页面请求正常发出
另外我注意到,你的项目看起来都已经开发很久了,为啥做了这么多之后才发现这个问题?是更新 Hx 版本导致这个问题吗?如果您有疑问,可以提供一个类似的可复现工程。
附带测试项目
这个是在做优化的时候发现的。会不会是因为http1.1的问题呢?我后续新建一个项目测试一下
我看了你这个测试项目,其实也是等index中的请求完成了之后,home页面中的请求才会完成。
你将index中请求时长设置久一点。那home的请求是不是就要一直等待index页面中的请求完成了之后才会成功呢,这种情况是不对的吧
@DCloud_UNI_yuhe 你看下这个复现工程
我们测试IOS也是一样的,我们的接口请求超时时间设置的是1分钟,其中A页面的接口会一直在请求。然后退出A页面,进入其他任何页面的接口请求都会阻塞,就好像还在队列中一样。只有等A页面的那个接口完成或者终止了,其他页面的接口请求才会成功,我们想要的是A页面的接口请求,不会影响到其他页面的接口,是否有办法能处理?
web平台不会出现这种情况是因为web是http2.0的。而APP端还是http1.x
@DCloud_UNI_yuhe 请问一下,这个是不是因为APP用的是http1.1的,所有接口请求都是复用一个通道,然后第一个接口的请求未完成,导致后面的接口请求还在队列,我们想避免这种情况有什么办法能处理吗?
你是测试 ios 真机还是模拟器有这个问题?安卓真机呢?
回复 DCloud_UNI_yuhe: 都是这个问题。安卓模拟器,安卓真机,IOS真机
回复 p***@163.com: 你服务器没有改什么东西吗?我今天测试的时候安卓模拟器也正常了,真奇怪了
回复 DCloud_UNI_yuhe: 没改啥东西。我刚刚重新用我发的那个http-test测试项目看还是一样的,我重新录一个完整的演示给你看下
回复 p***@163.com: 好的,不用,我这里也能复现这个问题,但就是平台有差异,我问一下
回复 DCloud_UNI_yuhe: 好的
回复 p***@163.com: 你好,看一下私信。
在uni-app中,如果整个应用的接口请求出现阻塞问题,通常是因为多个请求并发执行导致服务器压力过大,或者前端没有合理处理请求队列。以下是一些代码案例,展示如何在uni-app中处理这种情况,以避免接口请求阻塞。
1. 使用请求队列管理
可以使用一个简单的队列来管理请求,确保每次只有一个请求在执行。以下是一个简单的实现:
// 创建一个请求队列管理类
class RequestQueue {
constructor() {
this.queue = [];
this.isProcessing = false;
}
// 添加请求到队列
enqueue(requestFunc) {
this.queue.push(requestFunc);
this.processQueue();
}
// 处理队列中的请求
async processQueue() {
if (this.isProcessing || this.queue.length === 0) {
return;
}
this.isProcessing = true;
const requestFunc = this.queue.shift();
try {
await requestFunc();
} catch (error) {
console.error('Request failed:', error);
} finally {
this.isProcessing = false;
this.processQueue();
}
}
}
// 实例化请求队列
const requestQueue = new RequestQueue();
// 示例请求函数
function makeRequest(url) {
return () => uni.request({
url: url,
success: (res) => {
console.log('Request succeeded:', res);
},
fail: (err) => {
console.error('Request failed:', err);
}
});
}
// 添加请求到队列
requestQueue.enqueue(makeRequest('https://api.example.com/data'));
2. 使用节流(Throttle)或防抖(Debounce)
对于频繁触发的请求(如搜索框输入),可以使用节流或防抖技术来减少请求次数。以下是一个节流函数的示例:
function throttle(func, delay) {
let lastTime = 0;
return function(...args) {
const now = new Date().getTime();
if (now - lastTime >= delay) {
lastTime = now;
func.apply(this, args);
}
};
}
// 示例节流后的搜索函数
const throttledSearch = throttle(() => {
uni.request({
url: 'https://api.example.com/search',
data: {
query: searchInput.value
},
success: (res) => {
console.log('Search results:', res);
}
});
}, 1000); // 1秒节流间隔
3. 服务器端优化
虽然前端可以采取措施减少请求阻塞,但服务器端优化同样重要。确保服务器端能够处理并发请求,并优化数据库查询和数据处理逻辑。
以上代码案例展示了如何在uni-app中通过请求队列管理和节流技术来避免接口请求阻塞。根据具体应用场景,可以选择合适的方案来优化请求处理。