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

JavaScript中如何正确调用async函数?解决setLoading执行时机问题

正确处理Promise并控制loading状态的方案

你判断的没错,setLoading(false)确实会在Promise解析完成前就执行——因为Promise的回调属于异步任务,会被放到事件队列中等待执行,而同步代码setLoading(false)会优先完成,导致loading状态提前结束。

下面是两种可行的解决方案:

方案一:使用Promise的finally方法

直接在Promise调用链末尾添加finally,它会在Promise无论成功(resolve)还是失败(reject)后都执行,刚好适合用来重置loading状态:

const onPress = () => {
    setLoading(true);
    getEvents()
        .then((eventList) => setEvents(eventList))
        .catch((error) => alert(error))
        .finally(() => setLoading(false)); // 无论请求成功/失败都会执行
};

方案二:使用async/await语法

这种写法逻辑更线性,可读性更高:

const onPress = async () => {
    setLoading(true);
    try {
        // 等待getEvents的Promise完成
        const eventList = await getEvents();
        setEvents(eventList);
    } catch (error) {
        // 捕获请求失败的错误
        alert(error);
    } finally {
        // 无论成功失败都重置loading
        setLoading(false);
    }
};

额外优化:简化getEvents函数

你的getEvents手动包裹了一层Promise,其实完全没必要——因为firebase.firestore().collection('GoodEvents').get()本身就返回Promise,可以直接简化:

const getEvents = () => {
    return firebase.firestore().collection('GoodEvents').get()
        .then((snapshot) => {
            // 用map替代forEach+push,写法更简洁
            return snapshot.docs.map(doc => Event.fromFirestore(doc));
        });
};

如果get()请求失败,Promise会自动进入reject状态,上层的catch会捕获到错误,不需要手动在getEvents里处理reject。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 01:47:48