
pyscript 默认同步执行 python 代码,导致 dom 操作(如更新进度提示)延迟到脚本全部执行完毕才渲染;本文介绍通过 `asyncio` 配合 `await` 实现真正的实时 ui 反馈。
在 PyScript 中,Python 代码默认以同步方式运行于主线程,且浏览器的渲染机制会将 DOM 更新批量延迟至当前 JavaScript 任务(即整个
要突破这一限制,必须让 DOM 更新与长时间任务解耦,并主动让出控制权,使浏览器有机会重绘。PyScript 基于 Pyodide,完整支持 Python 的 asyncio,这是实现即时反馈的关键。
✅ 正确做法:使用 async/await + asyncio.sleep() 触发微任务调度
以下是一个可直接运行的最小化示例:
ShopNC多用户商城,全新的框架体系,呈现给您不同于以往的操作模式,更简约的界面,更流畅的搜索机制,更具人性化的管理后台操作,更适应现在网络的运营模式解决方案,为您的创业之路打下了坚实的基础,你们的需求就是我们的动力。我们在原有的C-C模式的基础上更增添了时下最流行的团购频道,进一步的为您提高用户的活跃度以及黏性提供帮助。ShopNC商城系统V2.4版本新增功能及修改功能如下:微商城频道A、商城
— 等待任务启动 —
import asyncio import js async def update_progress(message: str): js.document.getElementById("progress").textContent = message async def long_running_step(step_id: int) -> None: await update_progress(f"✅ 步骤 {step_id} 开始...") # 模拟耗时操作(例如数据处理、API 调用) await asyncio.sleep(2) # 注意:此处不可用 time.sleep()! await update_progress(f"✔️ 步骤 {step_id} 完成") async def main(): await update_progress("? 启动主流程...") for i in range(1, 4): await long_running_step(i) await update_progress("? 全部完成!") # 启动异步主函数(推荐写法) asyncio.create_task(main())
? 关键要点说明:✅ 必须使用 await asyncio.sleep(n)(而非 time.sleep(n)),因为后者是阻塞式调用,会彻底卡住事件循环;✅ asyncio.create_task(main()) 是推荐的启动方式(比 ensure_future 更现代、语义更清晰);✅ 所有 DOM 更新操作需封装在 async 函数中,并通过 await 显式让出控制权,确保每次更新后浏览器能及时渲染;✅ 若需调用真实耗时函数(如 pandas 计算、numpy 运算),应将其拆分为小块并插入 await asyncio.sleep(0) 强制调度,或使用 Web Worker(PyScript 尚不原生支持,需手动集成)。
⚠️ 注意事项
- 不要混合同步长循环(如 for i in range(1000000): ...)与 DOM 更新——这仍会导致界面卡死;
- js. 对象调用是同步的,但其效果是否“可见”取决于是否触发了浏览器重排/重绘机会,而 await 是获得该机会的最可靠方式;
- 如需更精细的进度控制(如百分比、取消按钮),可结合 js.Element.addEventListener 绑定用户交互,并使用 asyncio.Event 或共享状态变量协调。
通过合理运用异步编程模型,你不仅能实现实时进度反馈,还能保持 UI 响应性,真正发挥 PyScript 在浏览器端运行 Python 的潜力。









