我们时长有这样的需求,文件或图片每一次都从远端下载,导致离线状态页面空白,或者耗费带宽和时间太多导致的用户体验差,因此,我们需要一种方案去解决这样的问题
已经下载的文件或图片等资源,直接从从设备本地获取而不是从远端下载
解决思路
1、封装一个获取文件路径的函数,假如文件已经存在本地,则取本地路径,否则下载并返回下载路径
2、函数需要两个参数,一个是文件的下载路径,一个是与文件相关联的id,用来做文件与下载路径之间的关联
3、h5不支持文件存储,所以我们需要做条件编译
4、做一些异常的处理
以下是一个简单的处理函数,可以参考这样的思路去解决此类问题
注意:函数是盲写的,可能会出现bug,这个函数的用意是提供一个解决思路,大家也可以根据自己的需求去做修改
/*
* @description 获取文件的缓存路径,如果文件未缓存,则直接返回路径,并缓存
* @method getFileCache
* @param {String} filePath 完整的图片下载路径,如果没有从缓存中获取到,则用这个路径去下载
* @param {String} fileId 文件id,必须唯一,如guid
* @return {Object} promise对象
*/
export function getFileCache(filePath, fileId) {
const storageKey = 'IMAGE_CACHE_INFO'
return new Promise((resolve, reject) => {
try {
// #ifdef H5
// h5不进行缓存,直接下载
uni.downloadFile({
url: filePath, // 仅为示例,并非真实的资源
success: ({
statusCode,
tempFilePath
}) => {
(statusCode === 200) && return resolve(tempFilePath);
reject('下载失败');
},
fail: () => {
reject('下载失败');
}
});
// #endif
// #ifndef H5
// 首先获取本地存储的数据,查询是否有对应文件路径,如果有缓存内容,直接返回
const cacheFileInfo = uni.getStorageSync(storageKey);
cacheFileInfo[fileId] && return resolve(cacheFileInfo[fileId]);
// 如果没有,执行下载,并存储起来后
uni.downloadFile({
url: filePath, // 仅为示例,并非真实的资源
success: ({
statusCode,
tempFilePath
}) => {
(statusCode !== 200) && return reject('下载失败');
// 不管保存成功还是失败,都先将下载结果返回防止等待过长
resolve(tempFilePath);
saveFile(tempFilePath);
},
fail: (e) => {
reject('下载失败');
}
});
// 将文件下载至本地并存储
function saveFile(tempFilePath) {
uni.saveFile({
tempFilePath,
success: ({
savedFilePath
}) => {
// 因为请求是异步的,不能保证存储的时间,所以这里总是重新获取缓存内容
let storageInfo = Object.assign({}, uni.getStorageSync(storageKey));
storageInfo[fileId] = savedFilePath;
uni.setStorageSync(storageKey, storageInfo);
}
})
}
// #endif
} catch (e) {
console.error('getImageCache():::', e);
reject('下载失败'); // 出现异常,这里可以做一些异常处理
}
})
}
使用
getFileCache(downloadPath, fileId).then(path => {}).catch(e => {})
以上就是整个思路,函数比较粗糙,具体场景具体发挥~