新闻中心

从 Rust 调用 J*aScript 模块成员:使用 deno_core

2025-10-06
浏览次数:
返回列表

从 rust 调用 javascript 模块成员:使用 deno_core

本文档旨在指导开发者如何使用 deno_core 库,在 Rust 代码中加载 J*aScript 模块,并调用模块中导出的函数。我们将通过一个简单的示例,演示如何导出 J*aScript 函数并在 Rust 中调用它,最终实现 Rust 代码驱动 J*aScript 逻辑的能力。本文档包含完整的代码示例和详细的步骤说明,帮助读者快速上手。

步骤详解

以下步骤详细介绍了如何使用 deno_core 从 Rust 调用 J*aScript 模块中的函数。

  1. J*aScript 模块 (module.js):

    首先,创建一个简单的 J*aScript 模块,该模块导出一个名为 sum 的函数,该函数接受两个参数并返回它们的总和。

    // module.js
    export function sum(a, b) {
        return a + b;
    }
  2. Rust 代码 (main.rs):

    接下来,编写 Rust 代码来加载和执行 J*aScript 模块,并调用 sum 函数。

    use deno_core::{error::Error, FsModuleLoader, JsRuntime, RuntimeOptions};
    use std::rc::Rc;
    use tokio::runtime::Builder;
    use deno_core::resolve_path;
    use anyhow::Context;
    use v8::Local;
    
    fn main() -> Result<(), Error> {
        // 1. 创建 JsRuntime 实例
        let mut js_runtime = JsRuntime::new(RuntimeOptions {
            module_loader: Some(Rc::new(FsModuleLoader)),
            ..Default::default()
        });
    
        // 2. 创建 Tokio 运行时
        let runtime = Builder::new_current_thread()
            .enable_all()
            .build()?;
    
        // 3. 解析 J*aScript 模块路径
        let main_module = resolve_path(
            "./module.js",
            &std::env::current_dir().context("Unable to get CWD")?,
        )?;
    
        // 4. 定义异步任务
        let future = async move {
            // 5. 加载主模块
            let mod_id = js_runtime.load_main_module(&main_module, None).await?;
    
            // 6. 评估模块
            let result = js_runtime.mod_evaluate(mod_id);
    
            // 7. 运行事件循环
            js_runtime.run_event_loop(false).await?;
    
            // 8. 获取模块的命名空间
            let global = js_runtime.get_module_namespace(mod_id).unwrap();
            let scope = &mut js_runtime.handle_scope();
    
            // 9. 获取函数
            let func_key = v8::String::new(scope, "sum").unwrap();
            let func = global.get(scope, func_key.into()).unwrap();
            let func = v8::Local::<v8::Function>::try_from(func).unwrap();
    
            // 10. 创建参数
            let a = v8::Integer::new(scope, 5).into();
            let b = v8::Integer::new(scope, 2).into();
    
            // 11. 调用函数
            let func_res = func.call(scope, global.into(), &[a, b]).unwrap();
    
            // 12. 处理结果
            let func_res = func_res
                .to_string(scope)
                .unwrap()
                .to_rust_string_lossy(scope);
            println!("Function returned: {}", func_res);
    
            result.await?
        };
    
        // 13. 阻塞运行异步任务
        runtime.block_on(future)
    }

    代码解释:

    UXbot UXbot

    AI产品设计工具

    UXbot 185 查看详情 UXbot
    • 创建 JsRuntime: 使用 JsRuntime::new() 创建一个 J*aScript 运行时实例。RuntimeOptions 用于配置运行时,这里我们使用 FsModuleLoader 来加载文件系统中的模块。
    • 创建 Tokio 运行时: tokio 用于异步执行 J*aScript 代码。
    • 解析模块路径: 使用 resolve_path 函数将相对路径转换为绝对路径。
    • 加载主模块: js_runtime.load_main_module() 加载 J*aScript 模块。
    • 评估模块: js_runtime.mod_evaluate() 执行模块的代码。
    • 运行事件循环: js_runtime.run_event_loop() 运行 J*aScript 事件循环。
    • 获取模块命名空间: js_runtime.get_module_namespace() 获取模块导出的所有变量和函数。
    • 获取函数: 通过 global.get() 获取名为 "sum" 的函数。注意需要将获取到的值转换为 v8::Function 类型。
    • 创建参数: 使用 v8::Integer::new() 创建传递给 J*aScript 函数的参数。
    • 调用函数: 使用 func.call() 调用 J*aScript 函数。
    • 处理结果: 将 J*aScript 函数的返回值转换为 Rust 字符串。
    • 阻塞运行: runtime.block_on() 阻塞当前线程,直到异步任务完成。
  3. 运行代码:

    确保您已经安装了 Rust 和 deno_core 依赖。您可以使用以下命令将 deno_core 添加到您的项目中:

    cargo add deno_core
    cargo add tokio --features full
    cargo add anyhow

    然后,运行 Rust 代码:

    cargo run

    您应该会在控制台中看到输出 Function returned: 7,这表明您已成功从 Rust 调用了 J*aScript 函数。

注意事项

  • 错误处理: 在实际应用中,需要更完善的错误处理机制,例如使用 Result 类型处理 unwrap() 可能产生的错误。
  • 异步操作: deno_core 是基于异步的,因此需要使用 tokio 或其他异步运行时来执行 J*aScript 代码。
  • V8 类型转换: 在 Rust 和 J*aScript 之间传递数据时,需要进行 V8 类型转换。确保类型匹配,否则会导致运行时错误。
  • 模块加载器: FsModuleLoader 仅用于加载文件系统中的模块。如果需要从网络加载模块,需要实现自定义的模块加载器。

总结

通过本文档,您学习了如何使用 deno_core 库,在 Rust 代码中加载 J*aScript 模块并调用模块中的函数。这种技术可以用于构建混合应用,将 Rust 的高性能和 J*aScript 的灵活性结合起来。您可以使用类似的方法导出类(v8::Object)并访问其方法,从而实现更复杂的交互。记住,充分理解 V8 的类型系统和异步编程模型是至关重要的。

以上就是从 Rust 调用 J*aScript 模块成员:使用 deno_core的详细内容,更多请关注其它相关文章!


# 文件系统  # 手机关键词排名报价  # 网站推广的资源包括哪些  # 郑州seo张炎  # seo网站优化怎么做效果好  # 濠江区建设公示网站最新  # 佛山网站建设入门到精通  # 军营网站建设工作总结  # 崇明区网站建设介绍  # 合肥网站公司建设  # 泰州网站建设实训  # 如何实现  # 如何用  # javascript  # 创建一个  # 文档  # 可以使用  # 您可以  # 转换为  # 如何使用  # 加载  # 异步任务  # ai  # go  # js  # java 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: React Router v6 教程:构建认证保护的私有路由与重定向策略  Mac终端命令大全_Mac常用Terminal指令速查  使用 Pandas 高效处理 .dat 文件:字符清理与数据计算  Win11怎么用U盘重装系统 Win11制作启动盘并重装系统完整教程【详解】  qq邮箱发邮件给国外发不出去_QQ邮箱国际邮件发送失败原因与解决  小红书网页版入口链接分享 小红书官网直接进  J*a编写用户注册与登录功能_掌握字符串与验证逻辑  Adobe PDF表单中利用J*aScript解析与格式化日期组件的教程  漫蛙2在线漫画入口 漫蛙正版漫画网页版直达  Lar*el如何正确地在控制器和模型之间分配逻辑_Lar*el代码职责分离与架构建议  J*a实现学校排课程序_面向对象结构化项目示例  Lar*el递归关系中排除子孙节点的策略  Web Components中自定义开关组件状态同步的常见陷阱与解决方案  FullCalendar 自定义按钮样式定制指南  处理嵌套交互式控件:前端可访问性指南  响应式容器内容自动缩放与宽高比维持教程  J*a TimerTask中HashMap意外清空的深层原因与解决方案  在命令行怎么运行html项目_命令行运行html项目方法【教程】  期待已久:小米17 Ultra、小米首款NAS本月登场  钉钉视频会议声音异常如何处理 钉钉会议音频修复技巧  sublime如何只显示或隐藏特定类型文件_sublime侧边栏文件过滤  Tabulator表格日期时间排序问题及自定义解决方案  使用J*aScript检测输入元素是否包含在特定类中  如何将一个大型PHP应用拆分为多个Composer包_微服务与模块化架构的Composer实践  小红书商家版怎样在笔记嵌入商品卡路径_小红书商家版在笔记嵌入商品卡路径【挂载教程】  在J*aScript中复现SciPy的B样条拟合与求值:关键考量  css滚动动画效果怎么实现_使用Animate.css滚动触发动画类  Steam官网入口直达 Steam注册及登录步骤  漫蛙漫画官方主页入口 漫蛙MANWA网页直达访问链接  动漫花园资源网使用步骤_动漫花园资源网下载流程  深入理解J*a链表中的IPosition接口与使用  字由网在线版登录地址 字由网网页版安全入口  HTML元素状态管理:根据DIV内容动态启用/禁用按钮  ArrayList与LinkedList操作复杂度详解:遍历与修改  如何为你的Composer包编写自动化测试_集成PHPUnit到Composer的scripts工作流  sublime如何处理大型CSV文件的列对齐_sublime高级表格编辑插件指南  聚水潭ERP登录页面入口 聚水潭ERP官网登录界面  微博网页版首页入口 微博电脑端官网登录链接  使用CSS更改登录屏幕输入框中PNG图标颜色的策略与局限性  Win11怎么设置开机NumLock亮 Win11修改注册表InitialKeyboardIndicators值  Windows电脑怎么截图最方便_系统自带截图工具的5种神仙用法【技巧】  高德地图怎么看全景照片_高德地图全景照片浏览教程  Python多版本共存与虚拟环境管理深度指南  AO3镜像入口大全 AO3网页版内容访问全集  word邮件合并后日期格式不对怎么改_Word邮件合并日期格式修改方法  steam官方入口大全 steam账号注册及操作指南  Golang切片为何属于引用类型_Golang slice底层结构与引用语义说明  知音漫客正版漫画平台_知音漫客官网账号登录  响应式图片在网页设计中的正确实现方法  必由学官网首页入口 必由学教师网页版登录指南 

搜索