人人都会AI编程

8.2 命令调用:invoke 调用 Rust 命令

更新时间:2026-07-11

invoke 是前端与 Rust 后端通信的核心通道。通过它,你可以像调用普通异步函数一样,把参数传给 Rust,并拿回计算结果。整个过程受严格的类型检查和权限控制,既安全又直观。


基本用法

首先在前端安装 @tauri-apps/api,然后导入 invoke

import { invoke } from '@tauri-apps/api/tauri';

调用一个名为 greet 的 Rust 命令:

invoke('greet', { name: 'World' })
  .then((response) => console.log(response)) // "Hello, World!"
  .catch((error) => console.error(error));

Rust 端对应的命令:

#[tauri::command]
fn greet(name: String) -> String {
    format!("Hello, {}!", name)
}

并在 main 函数中注册:

fn main() {
    tauri::Builder::default()
        .invoke_handler(tauri::generate_handler![greet])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

参数与返回值

invoke 的第二个参数是一个普通对象,其键名必须与 Rust 函数的参数名一致。Rust 函数可以接收任意实现了 serde::Deserialize 的类型,包括结构体:

#[derive(Deserialize)]
struct User {
    name: String,
    age: u8,
}

#[tauri::command]
fn update_user(user: User) -> String {
    format!("User {} is {} years old", user.name, user.age)
}

前端调用:

invoke('update_user', { user: { name: 'Alice', age: 30 } });

返回值同样会自动序列化为 JSON 传给前端。你可以返回 String、数字、布尔值、对象、Vec<T> 等,只要它们实现了 serde::Serialize


错误处理

Rust 命令如果返回 Result<T, E>,Tauri 会自动处理:Ok 值正常返回;Err 会被转换成前端 Promise 的 rejection。
在 Rust 中:

#[tauri::command]
fn divide(a: f64, b: f64) -> Result<f64, String> {
    if b == 0.0 {
        Err("Division by zero".into())
    } else {
        Ok(a / b)
    }
}

前端捕获错误:

invoke('divide', { a: 10, b: 0 })
  .catch((err) => console.error(err)); // "Division by zero"

异步命令

如果 Rust 命令需要执行耗时操作(如读写大文件、网络请求),可以声明为 async 函数:

#[tauri::command]
async fn fetch_data(url: String) -> Result<String, String> {
    let response = reqwest::get(&url).await.map_err(|e| e.to_string())?;
    let body = response.text().await.map_err(|e| e.to_string())?;
    Ok(body)
}

前端仍然使用 invoke,无需任何更改,它始终返回 Promise。


类型映射速查

| 前端传递 | Rust 接收 |
|--------------------|---------------|
| "hello" | String |
| 42 | i32, u32, f64 等 |
| true / false | bool |
| [1, 2, 3] | Vec<T> |
| { key: "value" } | 结构体或 HashMap |
| null | Option<T> |


安全与权限

invoke 调用的命令必须已在 Rust 中显式注册,并且前端无法构造任意系统调用。所有参数都经过反序列化校验,避免了命令注入。此外,你可以通过 Tauri 的权限系统进一步限制哪些窗口或 URL 可以调用特定命令,这为多窗口应用提供了细粒度的安全控制。

一句话总结invoke 让前端与 Rust 之间的调用像本地函数一样自然,同时保持了类型安全和权限控制。