收藏
回答

使用downloadFile下载文件超时,文件较大的情况下载timeout时间内未能下完就报超时

框架类型 问题类型 API/组件名称 终端类型 微信版本 基础库版本
小程序 Bug downloadFile 微信安卓客户端 8.0.54 3.7.1

我是使用uniapp来写的,代码非常简单,主要关注downloadFile函数即可,就是一个下载功能,通过main函数传入的变量tempFileURLs下载文件

注意:

main函数中的tempFileURLs地址随时可能失效,请替换为其他的文件地址测试

问题:

例如我要下载的文件是54MB,但是用户的网络环境只能1MB/s,downloadFile设置的timeout是10秒,10秒到了之后就显示time out的报错了

难道time out 不是要失去服务器的连接后才报超时错误嘛? 难道说这个参数是指不论与服务器的连接是否断开,只要时间到了就报错?




	/**
	 * @desc 函数节流,单位时间内多次执行只执行一次
	 * @param func 函数
	 * @param wait 延迟执行毫秒数
	 * @param type 1 使用表时间戳,在时间段开始的时候触发 2 使用表定时器,在时间段结束的时候触发
	 */
	function throttle(func, wait = 1000, type = 1) {
		let previous = 0;
		let timeout;
		return function () {
			let context = this;
			let args = arguments;
			if (type === 1) {
				let now = Date.now();


				if (now - previous > wait) {
					func.apply(context, args);
					previous = now;
				}
			} else if (type === 2) {
				if (!timeout) {
					timeout = setTimeout(() => {
						timeout = null;
						func.apply(context, args)
					}, wait)
				}
			}
		}
	}
	async function main() {
		const tempFileURLs = "https://l36.gdl.netease.com/nshm_956773_v2.2.4_33e1ae06622da750e207760b3e94dd97.apk?key1=3ff60ef3effbb87fe7c9255811a6efea&key2=678d06d2"
		const objPath = `${wx.env.USER_DATA_PATH}/dictionary/`
		const fileName = "dictionary.br"
		downloadFile(tempFileURLs, objPath, fileName)
	}
	function downloadFile(link, objPath, fileName,timeout =
		10000) {
		return new Promise((resolve, reject) => {
			const csvDownloadTask = uni.downloadFile({
				url: link, //下载的url
				timeout: timeout,
				success: (res) => {
					if (res.statusCode === 200) {
						console.log(`文件${fileName}下载成功`, res);
						resolve(res)
						// return true
					} else {
						console.error(
							`文件${fileName}下载失败,code:${res.statusCode}`);
						reject(res.statusCode)
						return false
					}
				},
				fail(e) {
					console.error(`文件${fileName}下载失败:`, e);
					reject(e)
					return false
				}
			});
			csvDownloadTask.onProgressUpdate(throttle((res) => {
				console.log(`${fileName}展示进度obj:`, res);
				console.log(`${fileName}下载进度:${res.progress}`);
				console.log(
					`${fileName}已经下载的数据长度${res.totalBytesWritten}`);
				console.log(`${fileName}预期需要下载的数据总长度:${res
					.totalBytesExpectedToWrite}`);
			}, 300));
		})
	}




最后一次编辑于  01-19
回答关注问题邀请回答
收藏

2 个回答

  • 喵喵侠
    喵喵侠
    01-20

    解决方案建议

    • 调整超时时间:根据你要下载文件的大小和预计的网络速度,合理地设置timeout参数。例如,对于较大的文件,你可以根据文件大小和可能的最慢网络速度来估算一个合适的时间。如果文件大小为 54MB,网络速度最慢可能是 1MB/s,那么理论上下载时间至少需要 54 秒左右,你可以将timeout设置为大于这个时间的值,比如 60 秒(即timeout = 60000)。
    • 提供进度反馈和重试机制:在用户等待下载的过程中,你可以通过onProgressUpdate回调函数(如果downloadFile API 支持的话)来向用户展示下载进度。并且当出现超时错误时,提供一个方便用户重试的按钮,让用户可以重新发起下载。这样可以提高用户对下载功能的满意度。
    • 网络状态监测和提示:在发起下载之前,你可以先对用户的网络状态进行简单的监测。例如,通过uni.getNetworkType(在 uniapp 中)等函数来获取用户当前的网络类型(如 Wi - Fi、4G、3G 等),如果网络状态不佳,可以先提示用户,让用户选择是否继续下载。


    简单做就是把时间设置大一点,给一个友好的提示。


    01-20
    有用 1
    回复 1
  • sun
    sun
    发表于小程序端
    01-19

    downloadfile的超时是从开启下载开始算的,时间到了没下完就算超时。

    01-19
    有用
    回复 2
登录 后发表内容