上节继续,今天研究tauri中,前端如何调用Rust代码。

一、无返回值&无传参

main.rs中加1个hello方法:

然后在main方法中,参考下图暴露hello1:

Rust代码准备好之后,前端(假设是react框架)就能调用了:

import { invoke } from "@tauri-apps/api/tauri"

先引入invoke方法,然后在需要的地方:

运行效果:

二、有传参

/**
* 可传参
*/
#[tauri::command]
fn hello2(msg: String) {
println!("hello-2 {}!", msg);
}

多个方法暴露,参考下图:

前端调用:

<button onClick={() => invoke('hello2', { msg: "jimmy" })}>hello2</button>

三、有传参&有返回值

/**
* 有传参,带返回值
*/
#[tauri::command]
fn hello3(msg: String) -> String {
format!("hello-3 {}", msg)
}

前端调用:

  let hello3 = (message: String) => {
invoke("hello3", { msg: message }).then((message) => console.log(message))
}

四、返回复杂对象

use serde::{Deserialize, Serialize};

#[derive(Debug, Deserialize, Serialize)]
struct Person {
name: String,
age: i32,
} /**
* 返回复杂对象
*/
#[tauri::command]
fn get_person(name: String, age: i32) -> Result<Person, String> {
Ok(Person { name, age })
}

前端调用:

let get_person = (name: String, age: Number) => {
invoke("get_person", { name, age }).then((person) => console.log(person))
}

五、性能测试

很多功能,既然原生js与rust都能实现,谁的性能更高?

还是用经典的fibonacci做为示例:

/**
* 测试性能
*/
#[tauri::command]
fn fibonacci(n: i32) -> i32 {
if n <= 1 {
1
} else {
fibonacci(n - 1) + fibonacci(n - 2)
}
}

前端:

// js原生版的fibonacci (by:菩提树下的杨过 http://yjmyzz.cnblogs.com)
function fibonacci_js(n: number): number {
if (n <= 1) {
return 1;
}
return fibonacci_js(n - 2) + fibonacci_js(n - 1);
} function App() { //js版fibonacci测试
let js_test = (n: number) => {
let begin = new Date().getTime();
let result = fibonacci_js(n);
let end = new Date().getTime();
console.log(`fibonacci_js(${n})\t= ${result},\t执行时间: ${end - begin} ms`);
} //rust版fibonacci测试
let tauri_test = (n: number) => {
let begin = new Date().getTime();
invoke('fibonacci', { n }).then((result) => {
let end = new Date().getTime();
console.log(`fibonacci_tauri(${n})\t= ${result},\t执行时间: ${end - begin} ms`);
});
} ... <button onClick={() => js_test(38)}>fibonacci_js</button>
<button onClick={() => tauri_test(38)}>fibonacci_tauri</button>
... }

从输出耗时看,同样的硬件条件情况下,rust的实现,性能高于原生js,但略逊于wasm版本(可参见react+rust+webAssembly(wasm)示例 )

六、异常处理

Rust代码:

/**
* 异常处理
*/
#[tauri::command]
fn is_valid_age(age: i32) -> Result<String, String> {
if age > 0 && age < 150 {
Ok("pass".into())
} else {
Err(format!("age:{} invalid", age))
}
}

前端调用:

  let is_valid_age = (age: Number) => {
invoke("is_valid_age", { age })
.then((msg) => console.log(msg))
.catch((err) => console.error(err))
}

  

七、Rust异步处理

/**
* 异步方法
*/
#[tauri::command]
async fn method_1() -> String {
println!("method_1 is called");
//内部再调用另1个异步方法
let result = method_2();
//这里不会block,会继续执行下一句
println!("do another thing in method_1");
//这里会阻塞,直到method_2返回
let result = result.await;
println!("method_2 result:{} from method_1", result);
//返回method_2的结果
result
} async fn method_2() -> String {
println!("method_2 is called");
//刻意停3秒【注:必须先use std::{thread, time};】
thread::sleep(time::Duration::from_secs(3));
format!("method_2 result")
}

前端调用时,并无特别之处,仍按promise的套路处理:

  let async_test = () => {
invoke("method_1").then((result) => {
console.log("result:", result
);
})
}

Rust终端输出结果:

method_1 is called
do another thing in method_1
method_2 is called
method_2 result:method_2 result from method_1

  

八、访问tauri应用的window对象

#[tauri::command]
async fn get_window_label(window: tauri::Window) {
println!(
"Window: {},is_fullscreen:{:?}",
window.label(), //获取应用窗口的label
window.is_fullscreen() //获取应用是否全屏
);
}

  

九、state管理

注:这里的state可不是react组件的state,而是指tauri应用内部的状态,比如应用查询数据库前,要先判断下db的连接状态是否正常,就可以用上这个

struct DatabaseState {
connnted: bool,
} fn connect_db() -> DatabaseState {
DatabaseState { connnted: true }
} #[tauri::command]
fn query_data(state: tauri::State<DatabaseState>) {
assert_eq!(state.connnted, true);
println!("query data success")
}

这里我们定义了一个DatabaseState,然后在connect_db方法里,模拟连接上db后,将connected状态置成true,然后在query_data方法中,先判断db是否连上了。

在main方法中,就可以管理状态:

参考文章:

https://tauri.app/v1/guides/features/command

tauri学习(3)-前端调用Rust代码的更多相关文章

  1. 六、Android学习笔记_JNI_c调用java代码

    1.编写native方法(java2c)和非native方法(c2java): package com.example.provider; public class CallbackJava { // ...

  2. Android学习笔记_JNI_c调用java代码

    1.编写native方法(java2c)和非native方法(c2java): package com.example.provider; public class CallbackJava { // ...

  3. WebApi的前端调用

    WebApi前端调用 HTML代码: <!DOCTYPE html><html> <head> <meta charset="utf-8" ...

  4. 1.JAVA中使用JNI调用C++代码学习笔记

    Java 之JNI编程1.什么是JNI? JNI:(Java Natibe Inetrface)缩写. 2.为什么要学习JNI?  Java 是跨平台的语言,但是在有些时候仍然是有需要调用本地代码 ( ...

  5. 从零开始,学习web前端之HTML5开发

    什么是HTML5 HTML5是HTML最新的修订版本,2014年10月由万维网联盟(W3C)完成标准制定.是下一代 HTML 标准. 为什么要学习HTML5 HTML5定义了一系列新元素,如新语义标签 ...

  6. HTML5零基础学习Web前端需要知道哪些?

    HTML零基础学习Web前端网页制作,首先是要掌握一些常用标签的使用和他们的各个属性,常用的标签我总结了一下有以下这些: html:页面的根元素. head:页面的头部标签,是所有头部元素的容器. b ...

  7. 独家分享——大牛教你如何学习Web前端开发

    2014-12-18 14:35:42     引语 自从2008年接触网站开发以来到现在已经有六个年头了,今天偶然整理电脑资料看到当时为参加系里面一个比赛而做的第一个网站时,勾起了在这网站开发道路上 ...

  8. PL/SQL程序中调用Java代码(转)

    主要是学习PL/SQL调用JAVA的方法. 平台:WINDOWS 1.首先使用IDE写好需要调用的java代码,再添加"create or replace and compile java ...

  9. 4.C++中的函数重载,C++调用C代码,new/delete关键字,namespace(命名空间)

    本章主要内容: 1)函数重载 2)C++调用C代码 3)new/delete关键字实现动态内存分配 4)namespace命名空间 大家都知道,在生活中,动词和不同的名词搭配一起,意义都会大有不同,比 ...

  10. 如何高效的学习WEB前端

    IT 行业的变化快是众人皆知的,需要持续去学习新的知识内容.但是,往往我们工作之后,经常发现学习的东西很少了,学习效率非常低,感觉自己到了一个瓶颈期,久而久之,就演变成『一年工作经验,重复去用十年』的 ...

随机推荐

  1. windows 配置jdk8环境变量

    JAVA_HOME: E:\Android\Java\jdk1.8.0_131 PATH: %JAVA_HOME\%bin 也可以只配置PATH就可以,如 E:\Android\Java\jdk1.8 ...

  2. 为React组件库引入自动化测试:从零到完善的实践之路

    为什么我们需要测试? 我们的 React+TypeScript 业务组件库已经稳定运行了一段时间,主要承载各类UI展示组件,如卡片.通知等.项目初期,迫于紧张的开发周期,我们暂时搁置了自动化测试的引入 ...

  3. N+1查询:数据库性能的隐形杀手与终极拯救指南

    title: N+1查询:数据库性能的隐形杀手与终极拯救指南 date: 2025/05/06 00:16:30 updated: 2025/05/06 00:16:30 author: cmdrag ...

  4. vscode调试python时提示无法将“conda”项识别为 cmdlet、函数、脚本文件或可运行程序的名称的解决方法

    (1)vscode在调试python文件时提示如下信息: conda : 无法将"conda"项识别为 cmdlet.函数.脚本文件或可运行程序的名称.请检查名称的拼写,如果包括路 ...

  5. 明明是同一条SQL,为什么有时候走索引a,有时候却走索引b ?

    前言 想象你是一家餐厅的服务员,面前有两个菜单: 菜单A:按菜品分类排列(前菜.主菜.甜点) 菜单B:按价格从低到高排列 当顾客说:"我要最便宜的川菜". 你会: 先用菜单B找到所 ...

  6. K8s进阶之多租户场景下的资源配额(ResourceQuota)

    概述 ResourceQuota官方文档:https://kubernetes.io/zh-cn/docs/concepts/policy/resource-quotas/ 在 Kubernetes( ...

  7. MySQL 数字保留两位小数

    1.ROUND(x,d) 用于数据的四舍五入,ROUND(x)其实就是ROUND(x,0),也就是默认d为0:这里有个值得注意的地方是,d可以是负数,这时是指定小数点左边的d位整数位为0,同时小数位均 ...

  8. 20244104陈思淼 《Python程序设计》实验三报告

    课程:<Python程序设计> 班级:2441 姓名:陈思淼 学号:20244104 实验教师:王志强 实验日期:20254月20日 必修/选修: 公选课 1.实验内容 创建服务端和客户端 ...

  9. 【ASP.NET Core】调用 Web API 备份数据库

    老周不经意间翻了一下博客列表,上一篇水文竟然在 一个月前.啊,大海啊,全是水:时间啊,你跑得真快!过了一个月老周竟没感觉出来,可是这一个月里,好像啥事也没干成,就改了一下几个旧项目.也许是现在大环境真 ...

  10. IPMI新建BMC管理用户

    # 查看ipmi的ip [root@HOST-10-198-2-62 ~]# ipmitool lan print # 首先确认非admin用户的id,选择一个ID创建root用户 [root@HOS ...