JavaScript中用async/await管理多媒体资源需将加载过程封装为Promise:图片用Image对象监听onload/onerror,音视频监听canplay等事件;批量加载用Promise.allSettled实现错误隔离;结合UI反馈提升体验。

JavaScript 中用 async/await 管理多媒体资源(如图片、音频、视频)的异步加载,核心是把资源加载过程包装成 Promise,再用 await 等待其完成。这不是直接 await 元素属性,而是等待资源“加载就绪”这一状态。
图片资源:用 Image 对象 + Promise 封装
原生 Image 对象不返回 Promise,需手动封装:
async function loadImage(src) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => resolve(img);
img.onerror = () => reject(new Error(`Failed to load image: ${src}`));
img.src = src;
});
}
// 使用
async function renderAvatar() {
try {
const img = await loadImage('/avatar.jpg');
document.body.appendChild(img);
} catch (err) {
console.error(err.message);
}
}
音频/视频:监听 loadeddata 或 canplay 事件
load 事件只表示元素创建完成,不代表媒体已可播放;应等待解码就绪:
-
loadeddata:首帧数据已加载并可渲染(适合静音预加载) -
canplay:浏览器估算已有足够数据开始播放(更常用) -
canplaythrough:预计可连续播放到底(耗时较长,慎用)
封装示例:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
async function loadMedia(el, src) {
return new Promise((resolve, reject) => {
el.src = src;
const onLoaded = () => {
el.removeEventListener('canplay', onLoaded);
el.removeEventListener('error', onError);
resolve(el);
};
const onError = () => {
el.removeEventListener('canplay', onLoaded);
el.removeEventListener('error', onError);
reject(new Error(`Failed to load media: ${src}`));
};
el.addEventListener('canplay', onLoaded);
el.addEventListener('error', onError);
});
}
// 使用
async function initPlayer() {
const audio = document.getElementById('bgm');
try {
await loadMedia(audio, '/music.mp3');
audio.play(); // 此时可安全调用 play()
} catch (err) {
console.warn(err.message);
}
}
批量加载 + 错误隔离:用 Promise.allSettled
同时加载多个资源,且不因单个失败中断整体流程:
async function preloadAssets() {
const tasks = [
loadImage('/logo.png'),
loadMedia(document.getElementById('sfx1'), '/click.mp3'),
loadMedia(document.getElementById('sfx2'), '/hover.wav')
];
const results = await Promise.allSettled(tasks);
results.forEach((result, i) => {
if (result.status === 'fulfilled') {
console.log(`Asset ${i} loaded successfully`);
} else {
console.warn(`Asset ${i} failed:`, result.reason.message);
}
});
}
结合加载状态与用户体验
真实项目中建议配合 UI 反馈:
- 显示加载中 spinner 或占位图
- 加载成功后淡入、替换 DOM 或启用按钮
- 失败时显示重试按钮或降级内容(如用文字代替图片)
例如:
async function loadWithUI(src, container) {
container.innerHTML = '<div class="loading">Loading...</div>';
try {
const img = await loadImage(src);
container.innerHTML = '';
container.appendChild(img);
img.classList.add('fade-in'); // 配合 CSS transition
} catch (err) {
container.innerHTML = `<p class="error">⚠️ ${err.message}</p>`;
}
}

















