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

如何让ipywidget Button的on_click事件正常执行fabric-sdk-py异步方法

ipywidgets Button 绑定异步回调解决方案

问题根因

  • Jupyter 内核默认已运行一个 Asyncio 事件循环,直接调用asyncio.run()或loop.run_until_complete()会触发This event loop is already running报错
  • ipywidgets 的on_click回调默认不支持直接接收异步函数,直接传入async def定义的函数会触发协程未被等待的报错

实现方案

正确做法是在同步回调函数中调用asyncio.create_task(),将异步协程提交到当前正在运行的 Jupyter 事件循环中调度执行,示例代码如下:

import asyncio

# 异步业务逻辑,实现原本的交易查询逻辑
async def _check_id_async(b):
    x = await contract.evaluate_transaction('queryUnprotectedEntry', [_id_info.value], user)
    # 后续结果处理逻辑可直接写在这里,比如将返回结果赋值给页面展示组件
    print(f"查询结果: {x.decode('utf-8')}")

# 同步回调函数,作为on_click的绑定入口
def _check_id(b):
    # 提交异步任务到当前运行的事件循环
    asyncio.create_task(_check_id_async(b))

# 绑定同步回调
_check_id_button.on_click(_check_id)

可选:异常捕获封装

如果需要捕获异步任务执行过程中的异常,可以增加一层协程包装逻辑:

async def _task_catch_wrapper(coro):
    try:
        await coro
    except Exception as e:
        # 自定义异常处理,比如输出错误信息到notebook
        print(f"交易执行失败: {str(e)}")

def _check_id(b):
    asyncio.create_task(_task_catch_wrapper(_check_id_async(b)))

注意事项

  • 不要手动关闭、停止 Jupyter 内核自带的事件循环,会导致整个 notebook 运行异常
  • 异步函数中可以直接修改 ipywidget 组件的属性更新页面展示,不需要额外的调度逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 21:36:04