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

JavaScript天气APP:async函数processFormat未完成时showResults已执行

为什么await processFormat后仍无法获取到Fetch请求的数据?

我正在使用JavaScript Fetch API开发天气预报应用,希望在showResults函数中使用processFormat函数返回的数据,但无法实现——showResults函数总是在processFormat函数执行完成前就运行。我尝试在showResults函数第一行添加await processFormat(range);但没有效果,输出中的对象和数组都是空的,请问这是为什么?

const processFormat = async (range) => {
    let getCityUrl = `http://api.openweathermap.org/geo/1.0/direct?q=${city}&limit=${limit}&appid=${apiKey}`;
    //resultStates.length = 0; 
    fetch(getCityUrl)
    .then((response) => {
        return response.json();
    })
    .then((data) => {
        data.forEach((item) => {
            console.log(item);
            resultStates.push(item.state);
            resultObj[item.state] = {
                'lat': item['lat'],
                'lon': item['lon']
            };
        });
    })
    .catch(rejected => {
        console.log(rejected);
    })
    console.log(resultObj);
};
//...
const showResults = async (range) => {
    await processFormat(range);
    for (let i=0; i<Object.keys(resultObj).length; i++) {
        resultStates.push(Object.keys(resultObj)[i]);
    }
    console.log(`resultStates: ${resultStates}`)
    if (resultStates.length === 0) {
        resultSection.textContent = `Failed to find your city: ${city}. Try another city`;
        setTimeout(() => {
            resultSection.textContent = '';
            clickedSearch = 0;
        }, 5000);
    }
    else {
        //...
    }
};

问题根源

  • processFormat未真正等待异步操作:虽然给processFormat标记了async,但内部的fetch调用既没有被await,也没有返回Promise链。这导致processFormat会立刻返回一个已完成的Promise,showResults里的await根本不会等待fetch请求和后续数据处理完成。
  • 全局变量的时序冲突:你依赖的resultObj和resultStates是全局变量,它们的填充逻辑在fetch的回调函数中——这个回调要等网络请求完成后才会执行,而showResults的代码会在processFormat“假结束”后立刻运行,此时回调还没执行,全局变量自然是空的。

解决方法

1. 修复processFormat,让它真正等待异步操作

用await处理fetch和响应解析,同时直接返回处理好的数据(避免依赖全局变量):

const processFormat = async (range) => {
    const getCityUrl = `http://api.openweathermap.org/geo/1.0/direct?q=${city}&limit=${limit}&appid=${apiKey}`;
    try {
        // 等待fetch请求完成
        const response = await fetch(getCityUrl);
        // 等待响应解析为JSON
        const data = await response.json();
        
        const resultObj = {};
        const resultStates = [];
        
        data.forEach((item) => {
            console.log(item);
            resultStates.push(item.state);
            resultObj[item.state] = {
                lat: item.lat,
                lon: item.lon
            };
        });
        
        console.log(resultObj);
        // 返回处理好的结果
        return { resultObj, resultStates };
    } catch (err) {
        console.log(err);
        // 抛出错误让调用方处理
        throw err;
    }
};

2. 修改showResults,直接接收返回的数据

不再依赖全局变量,使用processFormat返回的结果完成后续逻辑:

const showResults = async (range) => {
    try {
        // 等待processFormat完成并获取返回的数据
        const { resultObj, resultStates } = await processFormat(range);
        
        console.log(`resultStates: ${resultStates}`);
        
        if (resultStates.length === 0) {
            resultSection.textContent = `Failed to find your city: ${city}. Try another city`;
            setTimeout(() => {
                resultSection.textContent = '';
                clickedSearch = 0;
            }, 5000);
        } else {
            // 此处编写后续处理逻辑,直接使用resultObj和resultStates即可
        }
    } catch (err) {
        // 处理请求失败的情况
        resultSection.textContent = `Request failed: ${err.message}`;
        setTimeout(() => {
            resultSection.textContent = '';
            clickedSearch = 0;
        }, 5000);
    }
};

额外提示

  • 尽量避免用全局变量传递异步操作的结果,直接返回数据能让代码逻辑更清晰,减少状态冲突风险。
  • 添加try/catch捕获错误,能更优雅地处理请求失败的情况,提升用户体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 01:44:54