如何处理同步异步函数结果?媒体预览总时长计算方案咨询
解决异步计算媒体预览总时长的问题
你的问题核心是同步函数无法等待异步操作完成就返回结果,必须把整个函数改成异步的,返回一个Promise,通过Promise.all等待所有媒体的时长计算完成后再求和。
具体实现步骤:
- 把
getItemsDuration改成返回Promise<number>类型,确保能等待所有异步操作结束后返回准确总时长 - 遍历媒体数组时,为每个媒体生成一个获取时长的Promise:
- 图片直接返回
Promise.resolve(5),把固定时长包装成Promise,统一处理逻辑 - 视频调用已有的
getVideoDurationPromise获取异步时长
- 图片直接返回
- 用
Promise.all等待所有Promise完成,得到所有媒体的时长数组后,用reduce累加求和
修改后的完整代码:
getItemsDuration(mediaArray: any): Promise<number> { // 生成所有媒体对应的时长Promise数组 const durationPromises = mediaArray.map(media => { const isVideo = !!(media.locationFile as any)?.type?.includes('video'); if (isVideo) { return this.getVideoDurationPromise(media.locationFile); } else { // 图片直接返回5秒的Promise return Promise.resolve(5); } }); // 等待所有Promise完成后累加总和 return Promise.all(durationPromises).then(durations => { return durations.reduce((total, duration) => total + duration, 0); }); } // 你的getVideoDurationPromise保持不变 private getVideoDurationPromise(file: File): Promise<number> { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => { const media = new Video(reader.result as string); media.onloadedmetadata = () => resolve(media.duration); }; reader.readAsDataURL(file); reader.onerror = (error) => reject(error); }); }
调用示例:
// 用.then方式获取结果 this.getItemsDuration(mediaArray).then(totalTime => { console.log('总预览时长:', totalTime); }).catch(error => { console.error('获取时长失败:', error); }); // 或者在async函数中用await async calculateTotalDuration() { try { const totalTime = await this.getItemsDuration(mediaArray); console.log('总预览时长:', totalTime); } catch (error) { console.error('获取时长失败:', error); } }
额外说明
- 如果某个视频获取时长失败,
Promise.all会直接reject,你可以根据需求调整:比如给失败的视频设置默认时长,把视频的Promise改成this.getVideoDurationPromise(...).catch(() => 10) Promise.all会并行处理所有异步操作,比逐个等待效率更高,适合批量处理媒体文件
内容的提问来源于stack exchange,提问作者lebanta
相关产品推荐
相关产品推荐

