2020-05-03 03:17:44
在JavaScript中,使用Promise可以更优雅地处理异步加载静态资源(如图片、CSS、JS等),避免回调地狱,提升代码可读性和可维护性。以下是具体实现方案及关键点说明:
一、基础实现:单资源加载以图片加载为例,核心逻辑是通过Promise封装异步操作,在资源加载成功时resolve,失败时reject:
function loadImg(imgSrc) { return new Promise((resolve, reject) => { const img = new Image(); // 创建Image对象 img.src = imgSrc; // 设置图片路径 img.onload = () => { console.log(`图片加载成功: ${imgSrc}`); resolve(img); // 传递图片对象供后续使用 }; img.onerror = () => { console.error(`图片加载失败: ${imgSrc}`); reject(new Error(`Failed to load image: ${imgSrc}`)); }; });}// 使用示例loadImg('src.jpg') .then(img => { document.body.appendChild(img); // 加载成功后插入DOM }) .catch(err => { console.error('处理错误:', err.message); });关键点:
当需要同时加载多个资源时,使用Promise.all()可实现并行加载+统一处理:
const imgList = ['1.jpg', '2.jpg', '3.jpg'];const promiseArray = imgList.map(src => loadImg(src));Promise.all(promiseArray) .then(images => { console.log('所有图片加载完成,数量:', images.length); images.forEach(img => document.body.appendChild(img)); }) .catch(err => { console.error('至少一张图片加载失败:', err.message); });关键点:
若需同时加载图片、CSS和JS文件,可统一封装Promise:
// 加载CSSfunction loadCSS(href) { return new Promise((resolve, reject) => { const link = document.createElement('link'); link.rel = 'stylesheet'; link.href = href; link.onload = () => resolve(link); link.onerror = () => reject(new Error(`CSS加载失败: ${href}`)); document.head.appendChild(link); });}// 加载JSfunction loadJS(src) { return new Promise((resolve, reject) => { const script = document.createElement('script'); script.src = src; script.onload = () => resolve(script); script.onerror = () => reject(new Error(`JS加载失败: ${src}`)); document.body.appendChild(script); });}// 并行加载混合资源Promise.all([ loadImg('1.jpg'), loadCSS('style.css'), loadJS('script.js')]) .then(() => console.log('所有资源加载完成')) .catch(err => console.error('资源加载出错:', err));四、错误处理优化精细化错误捕获:通过Promise.allSettled()获取每个Promise的结果(成功/失败):
Promise.allSettled(promiseArray) .then(results => { results.forEach((result, i) => { if (result.status === 'fulfilled') { console.log(`${imgList[i]} 加载成功`); } else { console.error(`${imgList[i]} 加载失败:`, result.reason.message); } }); });重试机制:对失败的操作自动重试:
function loadWithRetry(imgSrc, retries = 3) { return new Promise((resolve, reject) => { const attempt = () => { const img = new Image(); img.src = imgSrc; img.onload = () => resolve(img); img.onerror = () => { if (retries <= 0) reject(new Error(`重试次数耗尽: ${imgSrc}`)); else attempt(); // 递归重试 }; }; attempt(); });}通过Promise的链式调用和组合方法,可以清晰、高效地管理异步资源加载流程。