Async/Await未按预期执行等待逻辑问题求助
async/await 未按预期顺序执行,展示函数未等待获取数据完成
我尝试用async/await实现三步流程:
- 获取数据(fetch data)
- 展示数据(display data)
- 处理数据(process data)
每一步都是独立函数,要求前一步完成后再执行,但第二步展示数据的函数没有等待第一步获取数据完成就执行了。我反复修改代码,查了Stack Overflow、MDN文档和多篇async-await文章,还是没找到问题所在。
代码
HTML
<main> <div class="d-flex justify-content-around"> <div class="container row"> <div class="col-12" id="displayNumbers" style="min-height: 300px; border: 1px solid black;"></div> <div class="col-12"> <div class="btn" id="trigger" style="border: 1px solid red"> Async / Await </div> </div> </div> </div> </main> <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.6/dist/umd/popper.min.js" integrity="sha384-oBqDVmMz9ATKxIep9tiCxS/Z9fNfEXiDAYTujMAeBAsjFuCZSmKbSSUnQlmh/jp3" crossorigin="anonymous"> </script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.1/dist/js/bootstrap.min.js" integrity="sha384-7VPbUDkoPSGFnVtYi0QogXtr74QeVeeIs99Qfg5YCF+TidwNdjvaKZX19NZ/e6oz" crossorigin="anonymous"> </script> <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
JavaScript
var displayArea = document.getElementById("displayNumbers"); async function fetchNumbers(){ console.log("--fetchNumbers--") axios.get("http://numbersapi.com/random/year?json", ).then(function (response) { console.log("response fetchNumbers data:") console.log(response.data); numbersData = response.data; }) } async function displayNumbers(data){ console.log("--displayNumbers--") console.log(data); for (let d in data){ console.log(d); let div = document.createElement("div"); div.textContent = data[d].toString(); displayArea.appendChild(div); } } async function processNumbers(){ console.log("--processNumbers--") let divs = displayArea.querySelectorAll("div"); for (let div of divs){ const reg = new RegExp('^[0-9]+$'); if (reg.test(div.textContent)){ div.style = "background-color: black; color: white;" } } } var numbersData = {}; async function async_numbers(){ try{ await fetchNumbers(); await displayNumbers(numbersData); await processNumbers(); } catch(e){console.log("Error " + e)} } document.getElementById("trigger").addEventListener("click", async() => { async_numbers(); })
控制台输出
--fetchNumbers-- --displayNumbers-- Object { } --processNumbers-- response fetchNumbers data: Object { date: "April 29", text: "1623 is the year that a fleet of 11 Dutch ships depart for the coast of Peru, seeking to seize Spanish treasure on April 29th.", number: 1623, found: true, type: "year" }
可以看到--displayNumbers--在数据返回前就执行了,导致展示的是空对象。
编辑
我尝试给await axios.get添加错误处理:
try{ const response = await axios.get("http://numbersapi.com/random/year?json") console.log("response fetchNumbers data:") console.log(response.data); return response.data }catch(e){console.log("error handling")};
问题原因与解决方法
核心问题在于fetchNumbers函数里,你用了.then()处理axios请求,但没有等待这个Promise完成,也没有返回Promise。async函数如果内部没有等待异步操作,会直接返回一个已resolve的Promise,导致后续的await直接跳过,继续执行下一个函数。
正确的修改方式
- 给
axios.get加上await,替代.then(),并返回获取到的数据,避免使用全局变量numbersData(全局变量容易引发意外问题):
async function fetchNumbers(){ console.log("--fetchNumbers--") try { const response = await axios.get("http://numbersapi.com/random/year?json"); console.log("response fetchNumbers data:") console.log(response.data); return response.data; } catch(e) { console.log("获取数据出错:", e); throw e; // 抛出错误让外层try/catch捕获 } }
- 修改
async_numbers函数,接收fetchNumbers返回的数据,再传给displayNumbers:
async function async_numbers(){ try{ const data = await fetchNumbers(); await displayNumbers(data); await processNumbers(); } catch(e){console.log("Error " + e)} }
这样修改后,流程会严格按照获取数据→展示数据→处理数据的顺序执行:
await fetchNumbers()会等待axios请求完成并拿到数据后,才会执行下一步- 把获取到的数据直接传入
displayNumbers,不需要依赖全局变量,代码更健壮
为什么之前的写法不行?
你之前的fetchNumbers里,axios.get是异步操作,但你没有等待它完成,函数就直接结束了。async函数默认会返回一个resolved的Promise,所以await fetchNumbers()不会等待axios请求完成,直接往下执行displayNumbers,此时numbersData还是初始的空对象,就出现了你看到的顺序问题。
内容的提问来源于stack exchange,提问作者my-alt-account
相关产品推荐
相关产品推荐

