JavaScript async/await如何保证被调用函数执行完成后再继续后续逻辑
核心问题原因
你写的await串行调用逻辑本身没有语法错误,出现两个函数同时执行的核心原因是:colorVisited、colorPath这两个async函数内部的异步操作(比如延时染色、DOM动画、接口请求等带回调的逻辑)没有被正确纳入返回的Promise等待逻辑中,导致函数提前resolve,还没等内部逻辑跑完就进入了下一行代码的执行。
常见错误写法示例
比如你在colorVisited中用setTimeout做逐个节点染色时,如下写法则会提前返回:
// 错误示例:没有等待内部定时器执行完成就resolve colorVisited = async (visitedNodes) => { visitedNodes.forEach((node, index) => { setTimeout(() => { node.classList.add('visited-style') }, index * 50) }) return // 所有定时器刚注册完就直接返回,不等回调执行 }
修复方案
需要将两个子函数内部的所有异步操作包装成Promise,等待全部执行完成后再resolve函数本身的Promise:
// 正确示例:等待内部所有异步任务完成再返回 colorVisited = async (visitedNodes) => { // 把每个节点的染色异步操作包装成Promise const taskList = visitedNodes.map((node, index) => { return new Promise((resolve) => { setTimeout(() => { node.classList.add('visited-style') resolve() }, index * 50) }) }) // 等待所有染色任务执行完成 await Promise.all(taskList) return } // colorPath函数也按照同样逻辑修改内部异步操作的封装即可 colorPath = async (path) => { const taskList = path.map((node, index) => { return new Promise((resolve) => { setTimeout(() => { node.classList.add('path-style') resolve() }, index * 50) }) }) await Promise.all(taskList) return }
调用侧最终写法
子函数修复后,你原来的await写法就可以正常实现串行执行的效果:
helperDikjstras = async() => { // 执行相关前置逻辑 await this.colorVisited(visitedNodes); // 会等待所有访问节点染色完成再往下走 await this.colorPath(path); // 所有路径染色完成后才会结束当前函数 return; }
你之前尝试的then链式写法也可以正常使用,注意如果外部需要调用helperDikjstras并等待其执行完成,记得把Promise链返回即可:
helperDikjstras = async() => { // 执行相关前置逻辑 return this.colorVisited(visitedNodes).then(() => this.colorPath(path)); }
内容的提问来源于stack exchange,提问作者Sujio
相关产品推荐
相关产品推荐

