如何在Tauri命令中调用pick_file后返回数据?
问题:Tauri命令中等待文件选择完成并返回Base64的实现
我尝试通过Tauri命令选择文件,将其转换为base64后发送到Leptos视图,但无法实现等待文件选择完成。以下代码中,命令会立即返回,不会等待pick_file执行完毕:
//A simplified version of what I am trying to achive #[tauri::command] pub fn select_image<R: Runtime>(app_handle: tauri::AppHandle<R>) -> Option<String> { let mut file_base64: Option<String> = None; app_handle.dialog().file().pick_file(move |file_path| { //convert file_path to base64 }); //How to wait here for file pick to happen? return file_base64; }
我知道当前代码只是传入闭包后直接返回None,但不知道如何在命令中等待pick_file执行完成。或许我的实现思路有误?请指点如何达成需求。
解决方案
核心问题在于pick_file是异步回调式API,而你当前的命令是同步返回逻辑,因此需要将命令改为异步,通过通道等待回调结果返回:
- 使用
tokio::sync::oneshot创建单向通道,用于在回调中传递文件转换后的Base64结果 - 给Tauri命令添加
async属性,让框架支持异步命令调用 - 在命令逻辑中等待通道接收结果,完成后返回给前端
修改后的代码示例:
use tauri::Runtime; use tokio::sync::oneshot; use base64; #[tauri::command(async)] pub async fn select_image<R: Runtime>(app_handle: tauri::AppHandle<R>) -> Option<String> { // 创建oneshot通道,用于传递异步结果 let (sender, receiver) = oneshot::channel(); app_handle.dialog().file().pick_file(move |file_path| { let result = file_path.and_then(|path| { std::fs::read(path) .ok() .map(|content| base64::encode(content)) }); // 将结果发送到通道,忽略发送错误(比如接收端已关闭) let _ = sender.send(result); }); // 等待回调发送结果,返回最终值 receiver.await.unwrap_or(None) }
依赖配置
需要在Cargo.toml中添加以下依赖:
tokio = { version = "1.0", features = ["sync"] } base64 = "0.21.0"
替代方案:Asset Protocol
如果您也有类似需求,不必像我这样传递base64,可了解asset protocol。通过该协议,您可以通过http://asset.localhost/<full path to your asset>从appdata中访问资源,可查看asset protocol配置。
内容的提问来源于stack exchange,提问作者salman_sali
相关产品推荐
相关产品推荐

