st.cache_data缓存函数后st.status加载动画持续异常显示的问题
st.cache_data缓存函数后st.status加载动画持续异常显示的问题
嘿,我之前也碰到过这个坑!问题出在缓存函数里的UI状态更新逻辑不会在命中缓存时执行——当fetch_data()被缓存后,Streamlit会直接返回之前缓存的结果,完全跳过函数内部的所有代码,包括最后那句更新status状态的status.update(...)。这就导致你的状态框一直停留在“展开加载中”的状态,哪怕数据已经加载完成了。
给你两个可行的解决办法:
方法一:把UI状态逻辑移到缓存函数外(推荐)
把数据获取的纯逻辑和UI状态控制分开,缓存只负责处理数据,UI状态在外部控制,这样不管是否命中缓存,状态都能正确更新:
@st.cache_data(show_spinner=False) def fetch_data(): # 这里只保留数据获取的逻辑,去掉所有UI相关代码 time.sleep(2) game_data = scraper.get_data(game_list_input=games_id) data_df = scraper.get_data_df(data_list=game_data) games_data = data_df.to_pandas() return games_data # 把st.status放到缓存函数外面 with st.status("Buscando datos...", expanded=True) as status: games_data = fetch_data() # 不管是否命中缓存,执行到这里就更新状态 status.update(label="¡Descarga completada!", state="complete", expanded=False)
方法二:手动控制缓存与UI状态(适合需要保留函数内提示的场景)
如果你一定要在函数里保留状态提示,可以用st.session_state手动标记数据是否已加载,完全掌控UI流程:
# 用session_state来标记是否已经加载过数据 if "games_data" not in st.session_state: with st.status("Buscando datos...", expanded=True) as status: time.sleep(2) st.write("Partidos encontrados...") time.sleep(2) st.write("Descargando datos...") time.sleep(2) st.write("Dibujando tabla...") game_data = scraper.get_data(game_list_input=games_id) data_df = scraper.get_data_df(data_list=game_data) st.session_state.games_data = data_df.to_pandas() time.sleep(3) status.update(label="¡Descarga completada!", state="complete", expanded=False) games_data = st.session_state.games_data
这种方式相当于自己手动实现了缓存逻辑,同时能保证UI状态的每一步都能正确更新。
另外要注意:Streamlit的缓存机制是针对函数返回值的,函数内部的UI渲染、状态更新这类操作不会被缓存,也不会在命中缓存时执行,所以一定要把纯数据逻辑和UI逻辑分开,避免出现这种状态卡住的情况。
原问题描述:
这是我的代码:
@st.cache_data(show_spinner=False) def fetch_data(): with st.status("Buscando datos...", expanded=True) as status: time.sleep(2) st.write("Partidos encontrados...") time.sleep(2) st.write("Descargando datos...") time.sleep(2) st.write("Dibujando tabla...") game_data = scraper.get_data(game_list_input=games_id) data_df = scraper.get_data_df(data_list=game_data) games_data = data_df.to_pandas() time.sleep(3) status.update( label="¡Descarga completada!", state="complete", expanded=False ) return games_data games_data = fetch_data()缓存工作正常,
fetch_data()函数不会在每次刷新页面时执行,但加载动画一直在显示。我已经用了show_spinner=False但还是没用,就像下图显示的那样:
表格已经显示了,但加载动画还在那里。
补充说明:我用的是MLB API的爬虫,
get_data和get_data_df是爬虫类的方法,返回polars dataframe。
备注:内容来源于stack exchange,提问作者Ivan J.
相关产品推荐
相关产品推荐


