qs_xinchun2026_h5/utils/preload.js

128 lines
3.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// utils/preload.js
export class ImagePreloader {
constructor() {
this.cache = new Map();
}
/**
* 预加载单张图片
* @param {string} src - 图片地址
* @returns {Promise<boolean>}
*/
async preload(src) {
if (!src) return false;
// 检查缓存
if (this.cache.has(src)) {
return true;
}
// data URL 直接返回
if (src.startsWith('data:')) {
this.cache.set(src, true);
return true;
}
try {
// 本地图片和网络图片都需要真正加载
if (src.startsWith('/')) {
// 对于本地图片使用Image对象加载
await new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => resolve();
img.onerror = reject;
img.src = src;
});
this.cache.set(src, true);
console.log('本地图片预加载成功:', src);
return true;
} else {
// 对于网络图片使用uni.getImageInfo
await uni.getImageInfo({ src });
this.cache.set(src, true);
console.log('网络图片预加载成功:', src);
return true;
}
} catch (error) {
console.warn('图片预加载失败:', src, error);
this.cache.set(src, false);
return false;
}
}
/**
* 批量预加载图片
* @param {string[]} srcList - 图片地址数组
* @param {number} concurrency - 并发数
* @returns {Promise<Array<{src: string, success: boolean}>>}
*/
async preloadAll(srcList, concurrency = 3) {
const results = [];
const queue = [...srcList];
// 执行并发下载
const workers = [];
for (let i = 0; i < concurrency; i++) {
workers.push(this.worker(queue, results));
}
await Promise.all(workers);
return results;
}
async worker(queue, results) {
while (queue.length > 0) {
const src = queue.shift();
if (src) {
const success = await this.preload(src);
results.push({ src, success });
}
}
}
/**
* 清理缓存
*/
clearCache() {
this.cache.clear();
}
/**
* 预加载图片并设置到 img 标签
* @param {string} src - 图片地址
* @param {number} timeout - 超时时间
* @returns {Promise<string>} 返回图片临时路径
*/
async preloadToTemp(src, timeout = 10000) {
if (src.startsWith('/') || src.startsWith('data:')) {
return src;
}
return new Promise((resolve, reject) => {
const timer = setTimeout(() => {
reject(new Error('图片下载超时'));
}, timeout);
uni.downloadFile({
url: src,
success: (res) => {
clearTimeout(timer);
if (res.statusCode === 200) {
const tempPath = res.tempFilePath;
this.cache.set(src, tempPath);
resolve(tempPath);
} else {
reject(new Error(`下载失败: ${res.statusCode}`));
}
},
fail: (error) => {
clearTimeout(timer);
reject(error);
}
});
});
}
}
// 创建单例
export default new ImagePreloader();