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

JavaScript中fetch.then未在使用响应数据前完成执行的问题

解决异步数据加载前调用函数导致的空数组问题

你的核心问题是fetch是异步操作:脚本会先同步执行完所有同步代码(包括末尾的start()),之后才会执行fetch回调里的赋值逻辑,所以第一次调用start时firstList还是空数组。下面给你两种直接可行的解决方案:

方案1:在fetch回调里触发start

直接把start()放到fetch的成功回调中,确保只有当数据加载并解析完成后,才执行渲染逻辑:

let firstList = []
 
fetch(`${baseUrl}canList`, {
    method: 'GET'
}).then((response) => {
    return response.json() // 简化嵌套的then链,更易读
}).then((jsonResponse) => {
    firstList = jsonResponse
    start() // 数据就绪后再调用start
}).catch((err) => {
    console.log(`Error: ${err}`)
})

方案2:用async/await正确实现(修正你之前的尝试)

如果你想用async/await,得把整个数据加载+渲染的逻辑放到async函数里,确保等待fetch完成后再调用start:

let firstList = []

async function loadAndRender() {
    try {
        const response = await fetch(`${baseUrl}canList`, { method: 'GET' })
        firstList = await response.json()
        start() // 等数据加载完再执行渲染
    } catch (err) {
        console.log(`Error: ${err}`)
    }
}

loadAndRender() // 执行这个异步函数,替代原来直接调用的start()

你之前尝试async/await没成功,大概率是只包装了fetch但没等待结果,或是没在异步函数里调用start,上面的写法能帮你避开这个问题。

额外优化建议

可以去掉全局变量的依赖,把数据直接传给start函数,逻辑更清晰:

// 修改start函数,接收数据参数
function start(listData) {
    listBox.innerText = ''
    const listContainer = document.createElement('div') // 加上const,避免全局变量污染
    listContainer.classList.add('text-container')
    listBox.append(listContainer)  
    listData.forEach(el => {
        const div = document.createElement('div')
        div.innerText = el
        listContainer.appendChild(div) // 直接用创建好的变量,不用重复querySelector
    })
    addstyle()
}

// 对应修改fetch的回调
.then((jsonResponse) => {
    start(jsonResponse) // 直接把数据传入start
})

// 或者async/await里
start(await response.json()) // 一步到位,甚至可以不用firstList全局变量

内容的提问来源于stack exchange,提问作者Jon Stewart

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 12:45:15