如何让示例中的setTimeout实现顺序执行?
问题分析
你当前的代码核心问题是:外层Promise在map遍历执行完毕后立刻调用了resolve(),完全没有等待所有setTimeout的回调执行完成。这就导致await直接结束,后续代码(比如第二个函数)会提前启动,和所有异步回调并行执行,违背了“先完成第一个函数所有操作再执行第二个”的需求。
修正方案
方案1:并行调度但等待全部回调完成(保留原延迟触发逻辑)
把每个setTimeout包装成独立的Promise,通过Promise.all等待所有回调执行完毕后,再resolve外层Promise。这样既保留了原有的“第n行延迟n秒触发”的并行调度逻辑,又能确保所有操作完成后再执行后续代码。
const matrix = [ [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], ]; async function displayHorizontalPatterns() { console.log("HORIZONTAL start"); await new Promise((resolve) => { // 把每个setTimeout包装为Promise并收集 const timeoutTasks = matrix.map((el, idx) => { return new Promise((innerResolve) => { setTimeout(() => { el.fill(1); console.log(matrix); el.fill(0); innerResolve(); // 标记当前setTimeout任务完成 }, idx * 1000); }); }); // 等待所有异步任务完成后,再结束外层Promise Promise.all(timeoutTasks).then(resolve); }); console.log("HORIZONTAL end"); } // 示例第二个函数 async function displayVerticalPatterns() { console.log("VERTICAL start"); // 这里写第二个函数的业务逻辑 console.log("VERTICAL end"); } // 按顺序执行两个函数 displayHorizontalPatterns().then(displayVerticalPatterns);
方案2:严格顺序执行异步操作(逐行完成后再处理下一行)
如果你的需求是逐行依次执行(第一行动画完成后再启动第二行),可以用for...of循环配合封装的延迟函数实现,确保操作严格按顺序完成:
const matrix = [ [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], ]; // 封装通用延迟函数 function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } async function displayHorizontalPatterns() { console.log("HORIZONTAL start"); // 用for...of顺序遍历,每次等待当前行操作完成再进行下一行 for (const row of matrix) { row.fill(1); console.log(matrix); row.fill(0); await delay(1000); // 等待1秒后处理下一行 } console.log("HORIZONTAL end"); } // 示例第二个函数 async function displayVerticalPatterns() { console.log("VERTICAL start"); // 这里写第二个函数的业务逻辑 console.log("VERTICAL end"); } // 按顺序执行两个函数 displayHorizontalPatterns().then(displayVerticalPatterns);
方案区别
- 方案1:所有行的
setTimeout会被同时调度,总耗时约等于最后一行的延迟时间(5秒),适合需要并行触发但必须等待全部完成的场景。 - 方案2:逐行执行,总耗时为行数×单步延迟(5秒),适合需要严格顺序的动画或流程场景。
内容的提问来源于stack exchange,提问作者Vladimir
相关产品推荐
相关产品推荐

