Node.js中如何解决异步回调里Push函数无法存储视频时长到数组的问题
解决Node.js中异步获取视频时长无法存入数组的问题
嗨,我来帮你搞定这个问题!其实你遇到的核心问题不是push函数失效,而是异步代码的执行时机没搞对——听我慢慢给你拆解:
为什么第一个代码里console.log看不到内容?
getVideoDurationInSeconds是一个异步函数,它返回的是Promise对象,.then()里的代码会等视频时长获取完成后才会执行。但你的console.log(durations)是在forEach循环同步执行完立刻就跑了,这时候所有.then()里的push操作都还没触发呢!所以你打印出来的是空数组,但实际上后续push是会执行的,只是你没等到它完成就看结果了。
而第二个代码里的durations.push(doc)是同步执行的,循环跑一遍就把所有doc塞进数组了,所以打印自然能看到内容。
正确的解决方案
这里推荐两种清晰的处理方式,都是为了确保等所有异步操作完成后再去访问数组:
方式1:用async/await + Promise.all(最推荐)
这种方式会并行处理所有视频的时长请求,效率高,代码也更简洁:
async function collectVideoDurations() { // 先把所有获取时长的Promise收集起来 const durationPromises = files.map(doc => { return getVideoDurationInSeconds(`uploads/skill1/${doc}`); }); // 等待所有Promise都完成,直接得到装满时长的数组 const durations = await Promise.all(durationPromises); console.log(durations); // 这里就能看到完整的时长数组啦 } // 记得调用这个异步函数 collectVideoDurations();
方式2:通过计数判断所有异步操作完成
如果你不想用Promise.all,也可以手动统计已完成的异步任务数量,等全部完成后再打印:
const durations = []; let completedTasks = 0; files.forEach(doc => { getVideoDurationInSeconds(`uploads/skill1/${doc}`).then(duration => { durations.push(duration); completedTasks++; // 当完成的任务数等于文件总数时,说明所有时长都获取完了 if (completedTasks === files.length) { console.log(durations); } }); });
小提醒
异步代码的逻辑和同步代码不一样,不能用“写完代码就立刻拿到结果”的同步思维去处理。必须通过.then()、async/await这类异步语法,确保在所有异步操作完成后再去访问结果哦!
内容的提问来源于stack exchange,提问作者Umer Affaq
相关产品推荐
相关产品推荐

