JavaScript异步执行疑问:如何在cookPopcorn运行时并行执行makingDrinks
JavaScript异步并行实现:电影夜场景优化方案
问题核心
你遇到的问题是错误地用await强制了串行执行:当你在makingDrinks()前先await cookPopcorn()时,async函数会暂停,直到爆米花加热完成才会继续执行后面的调饮料代码,自然无法实现并行。
答案:完全可以实现并行,你确实误解了async/await的使用场景
async/await本质是Promise的语法糖,await的作用是暂停当前async函数的执行,等待单个Promise完成。如果要让多个异步任务并行,你需要先同时启动所有异步任务(获取它们的Promise对象),再根据业务逻辑按需等待这些Promise的结果。
正确实现步骤
根据你的需求,正确的流程应该是:
- 同时启动爆米花加热和调饮料的异步任务
- 等待爆米花加热完成,执行撒盐操作
- 等待饮料准备完成,启动电影
示例代码(符合你的需求)
// 模拟爆米花加热(分阶段异步) function cookPopcorn() { return new Promise(resolve => { console.log("微波炉启动:开始加热爆米花(阶段a)"); setTimeout(() => { console.log("爆米花加热阶段b"); setTimeout(() => { console.log("爆米花加热阶段c"); setTimeout(() => { console.log("爆米花加热完成!"); resolve(); }, 1000); }, 1000); }, 1000); }); } // 模拟调饮料(异步操作) function makingDrinks() { return new Promise(resolve => { console.log("开始调饮料:拿杯子"); setTimeout(() => { console.log("倒汽水"); setTimeout(() => { console.log("加冰块"); setTimeout(() => { console.log("饮料准备完成!"); resolve(); }, 800); }, 800); }, 800); }); } // 模拟撒盐(异步操作) function addSalt() { return new Promise(resolve => { console.log("给爆米花撒盐..."); setTimeout(() => { console.log("撒盐完成!"); resolve(); }, 500); }); } // 模拟播放电影 function startMovie() { console.log("🎬 开始播放电影!"); } // 优化后的电影夜流程 async function movieNight() { // 关键:同时启动两个异步任务,不立即await const popcornPromise = cookPopcorn(); const drinkPromise = makingDrinks(); // 等待爆米花完成后撒盐 await popcornPromise; await addSalt(); // 等待饮料完成后启动电影 await drinkPromise; startMovie(); } movieNight();
执行效果说明
运行这段代码,你会看到调饮料的操作(拿杯子、倒汽水、加冰块)会穿插在爆米花的a、b、c加热阶段之间执行,完全符合你的并行需求。最后会在撒盐完成且饮料准备好后启动电影。
关键注意点
- 不要在启动第二个异步任务前
await第一个任务,否则会变成串行 - 先保存所有异步任务的Promise对象,再按需
await,是实现异步并行的核心 - 如果需要等待多个任务全部完成后再执行下一步,可以用
Promise.all([promise1, promise2]),但你的场景中撒盐必须在爆米花之后,所以不能直接用all,需要拆分等待逻辑
内容的提问来源于stack exchange,提问作者Bram
相关产品推荐
相关产品推荐

