我有一个在 Bokeh 服务器上运行的应用程序,它呈现数据。
数据的计算有点昂贵,我想在完成时显示一个加载屏幕。
当服务器打开并且我正在更改参数时,到目前为止使用
curdoc().add_next_tick_callback()
效果很好,如Force update of bokeh widgets?.
但是,在最初打开文档时(即我打开
http://localhost:5006/my_application
时),延迟根本不起作用。main.py:
from bokeh.plotting import curdoc
from main_frame import MainFrame
print('start')
# the constructor contains code to create a loading screen
main_frame = MainFrame()
curdoc().add_root(main_frame.layout)
curdoc().add_next_tick_callback(lambda: main_frame.plot('initial_file_name'))
print('after adding callback')
如果我删除最后一行,加载屏幕会正常显示,但显然没有计算完成。
最后一行显示初始数据,而不是在计算期间首先显示加载屏幕。
我在计算中有一些控制台输出,它清楚地表明计算是在创建连接之前完成的:
初始启动:
> bokeh serve my_application
2023-03-15 14:27:32,064 Starting Bokeh server version 2.4.3 (running on Tornado 6.1)
2023-03-15 14:27:32,064 User authentication hooks NOT provided (default user enabled)
2023-03-15 14:27:32,064 Bokeh app running at: http://localhost:5006/my_application
2023-03-15 14:27:32,064 Starting Bokeh server with process id: 5368
当
http://localhost:5006/my_application
打开时:
start
after adding callback
<output from my computation>
2023-03-15 14:28:36,984 WebSocket connection opened
2023-03-15 14:28:36,984 ServerConnection created
我所期望的:
start
after adding callback
2023-03-15 14:28:36,984 WebSocket connection opened
2023-03-15 14:28:36,984 ServerConnection created
<output from my computation>
有什么技巧可以使事情正常进行吗?
编辑:我尝试使用
curdoc().add_timeout_callback(lambda: main_frame.plot('initial_file_name'), 1000)
编辑:我做了另一个测试并使用了一个需要更长的时间 [大约三秒] 的绘图输入。下一个报价回调,加载屏幕仍然没有显示。
对于超时回调,这是非常奇特的:它只在我有一些最小超时值时显示加载屏幕。值 500 不会导致显示加载屏幕,值 800 会。在这两种情况下,计算运行之后都会有明显的延迟。我怀疑初始渲染需要 500 到 800 毫秒,并且只有在绘图延迟之后才有效。
显然使用超时回调将是一个糟糕的解决方案。
设法自己解决了。 工作代码:
from bokeh.plotting import curdoc
from bokeh.events import DocumentReady
from main_frame import MainFrame
main_frame = MainFrame()
curdoc().add_root(main_frame.layout)
def render_initial(event):
main_frame.plot('initial_file_name')
curdoc().on_event(DocumentReady, render_initial)