You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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直接跳过,继续执行下一个函数。

正确的修改方式

  1. 给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捕获
  }
}
  1. 修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 13:55:21