如何在非同步回调中​​使用异步移动闭包?

时间:2021-06-19 05:26:00

标签: asynchronous rust

这是一个fltk按钮的点击回调函数,我想通过点击一个按钮来执行一个数据库查询。

    //button click even
    ui.but.set_callback(async move |_| {
        let txt = "Some long text!Some long text!Some long text!Some long text!Some long text!\n";
        log.buffer().unwrap().append(txt);
        my_db::sqlserver_mod2::sql2().await.unwrap();
    });

我有一个错误:

[E0308] mismatched types. 
[Note] expected `()`, found opaque type

如何在非同步回调中​​使用异步移动闭包?

1 个答案:

答案 0 :(得分:0)

set_callback() 的签名是:

fn set_callback<F: FnMut(&mut Self) + 'static>(&mut self, cb: F) 

换句话说,回调不能返回任何东西。但是你的回调

async move |_| {
  //skipped      
});

有一个返回类型:

impl Future<Output=()>

这是一个不返回任何内容的匿名未来。所以你不能使用异步闭包作为你的回调。

相反,您应该传递预期类型的​​闭包并在其中进行处理:

ui.but.set_callback(move |_| {
        let txt = "Some long text!Some long text!Some long text!Some long text!Some long text!\n";
        log.buffer().unwrap().append(txt);

         //acquire a runtime somehow, see the docs of your preferred runtime
        runtime.spawn(async {
            my_db::sqlserver_mod2::sql2().await.unwrap();
        });

    });

最后但并非最不重要的 - 您应该避免在 UI 内进行缓慢的操作,因为它会显得无响应。考虑将工作卸载到另一个线程。例如,您可以启动 tokio 并预生成您的处理程序,这些处理程序应该在生产者-消费者模型中工作,并且只需通过来自 UI(生产者)的通道传递命令。