从 Rust 调用 JavaScript 模块成员:使用 deno_core

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

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

步骤详解

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

JavaScript 模块 (module.js):

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

立即学习“Java免费学习笔记(深入)”;

// module.jsexport function sum(a, b) {    return a + b;}

Rust 代码 (main.rs):

接下来,编写 Rust 代码来加载和执行 JavaScript 模块,并调用 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 {    // 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. 解析 JavaScript 模块路径    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::::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)}

代码解释:

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

运行代码:

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

cargo add deno_corecargo add tokio --features fullcargo add anyhow

然后,运行 Rust 代码:

cargo run

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

注意事项

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

总结

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1526891.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月20日 18:55:53
下一篇 2025年12月8日 21:51:58

相关推荐

  • CSS模态窗口内容布局指南:解决内容溢出与定位问题

    本文旨在解决CSS模态窗口中内容显示不正确或溢出容器的问题。核心在于深入理解HTML结构与CSS样式的协同作用,强调将所有模态窗口内部元素正确嵌套在负责内容渲染的容器(如内层div)中。通过清晰的结构和恰当的CSS布局,确保模态窗口内容始终按预期显示在可见区域内,提升用户体验。 模态窗口内容溢出问题…

    好文分享 2025年12月20日
    000
  • 代理 Function.prototype 的正确姿势

    本文旨在阐明为何直接代理 Function.prototype 会失败,并提供一种通过 Object.defineProperty 来保护 Function#toString() 不被覆盖,从而实现类似代理功能的解决方案。文章详细解释了 Function.prototype 的属性特性,并通过代码示…

    2025年12月20日
    000
  • JavaScript页面加载事件:解决元素内容短暂回滚的常见问题

    本文旨在解决JavaScript中一个常见问题:页面元素内容在加载后短暂改变又迅速恢复原状。核心原因在于 window.addEventListener 错误地使用了 onload 作为事件名,而非正确的 load。文章将深入探讨 load 事件的正确用法,并介绍 DOMContentLoaded …

    2025年12月20日
    000
  • Font Awesome 图标突然消失?排查与解决方案

    当 Font Awesome 图标在未修改任何代码的情况下突然无法显示时,通常表明问题源于外部服务而非本地代码错误。本文将指导您如何通过检查 Font Awesome 的官方服务状态页面来快速诊断此类问题,并回顾正确的集成方式,确保您的图标能持续稳定地呈现。 Font Awesome 图标显示异常的…

    2025年12月20日
    000
  • JavaScript中的Web Cryptography API如何保证数据安全?

    Web Cryptography API通过安全密钥管理、标准算法支持、数据完整性验证和浏览器沙箱执行,确保前端加密可靠性。1. 密钥不可提取且由crypto.subtle.generateKey()生成,防止泄露;2. 内置AES-GCM、RSA-OAEP、HKDF、PBKDF2、SHA-256等…

    2025年12月20日
    000
  • 利用 Flipper 快速定位 React Native 组件源代码

    本文介绍了如何使用 Flipper 这款强大的 React Native 调试工具,快速定位应用中特定组件的源代码位置。通过 Flipper 的 Inspector 功能,开发者可以方便地查看组件的层级结构,并直接跳转到代码编辑器中对应的代码行,极大地提升开发效率。 在 React Native 开…

    2025年12月20日
    000
  • 在JavaScript中,函数式编程范式如何改变我们的代码组织方式?

    函数式编程通过纯函数、不可变数据和函数组合提升代码可预测性与可维护性。1. 纯函数确保输入输出一致,不依赖外部状态,如用 (a, b) => a + b 避免全局变量;2. 不可变数据避免副作用,使用 map、filter 或展开运算符生成新值;3. 函数组合将小函数如 trimInput、v…

    2025年12月20日
    000
  • MongoDB 动态查询:获取集合中最近N年的数据

    本文详细介绍了如何在 MongoDB 中动态查询集合内最近N年的数据,而非基于当前系统时间。通过利用聚合管道的 $setWindowFields、$sort 和 $limit 等阶段,我们能够智能地识别集合中的最新日期,并以此为基准,灵活地提取指定时间范围内的记录,无需硬编码日期,极大地提升了查询的…

    2025年12月20日
    000
  • JavaScript中form.submit()无效的原因:DOM连接的重要性

    本文旨在解释为什么在JavaScript中,当表单未连接到DOM(文档对象模型)时,form.submit()方法无法正常工作。我们将深入探讨HTML规范,揭示表单提交过程中的关键限制,并提供相应的解释和示例。理解DOM连接对于正确处理表单提交至关重要。 在JavaScript中,使用form.su…

    2025年12月20日
    000
  • CSS Margin 错位问题排查与 Flexbox 解决方案

    本文旨在解决 CSS margin 属性应用位置错误的问题,特别是当元素使用了 float 属性后,可能导致 margin 应用到页面顶部而不是预期位置。文章将深入分析问题原因,并提供使用 Flexbox 布局替代 float 的解决方案,帮助开发者更有效地控制页面元素定位,避免类似布局问题的发生。…

    2025年12月20日
    000
  • 解决Django模态窗口内容溢出问题:结构与布局指南

    本教程旨在解决Web开发中,尤其是Django项目中常见的模态窗口内容溢出、不显示在预期容器内的问题。核心在于强调正确的HTML结构,确保所有模态内容都必须嵌套在内部模态容器元素中,以充分利用CSS定义的样式和布局属性,从而实现模态窗口的预期显示效果和功能。 模态窗口内容溢出问题的根源分析 在构建w…

    2025年12月20日
    000
  • 如何利用 JavaScript 实现一个简单的语音识别或合成应用?

    答案:使用Web Speech API可实现语音识别与合成。首先检查浏览器支持情况,SpeechRecognition用于将语音转文本,需配置语言及参数并监听结果;SpeechSynthesis则将文本转语音,通过设置utterance属性并调用speak()播放。结合二者可构建简单语音助手,注意需…

    2025年12月20日
    000
  • 使用 D3.js 根据节点数量动态调整文本字体大小

    本文介绍了如何使用 D3.js 动态调整文本节点的字体大小,使其能够根据节点数量或可用空间进行自适应调整。通过计算节点间的距离和文本宽度,并循环调整字体大小,最终实现文本在有限空间内的最佳显示效果。本文提供详细的代码示例,帮助开发者解决节点数量过多导致文本显示拥挤的问题。 在使用 D3.js 创建可…

    2025年12月20日
    000
  • 代理 Function.prototype 的正确方法

    本文将深入探讨如何安全且正确地代理 Function.prototype,特别是 toString 方法。如同摘要所述,直接修改 Function.prototype 可能会导致意想不到的问题,因此我们需要采用更严谨的方法。 为什么直接代理 Function.prototype 不可行? 直接尝试通…

    2025年12月20日
    000
  • 使用模板字符串解决 JavaScript 中链接内的美元符号问题

    本文旨在解决 JavaScript 项目中在链接字符串中使用美元符号导致的问题。通过使用模板字符串(Template literals),可以轻松地在链接中嵌入变量,避免出现解析错误。本文将详细介绍模板字符串的使用方法,并提供示例代码,帮助开发者更好地理解和应用。 在 JavaScript 项目中,…

    2025年12月20日
    000
  • 修改 标签前两个单词的字体大小:JavaScript 教程

    标签前两个单词的字体大小:javascript 教程” /> 本文将介绍如何使用 JavaScript 获取 标签中的前两个单词,并修改它们的字体大小。通过提取 标签的文本内容,将其分割成单词数组,然后选取前两个单词进行样式修改,从而实现对特定文本的精准控制。文章将提供详细的代码示…

    2025年12月20日
    000
  • JavaScript中的事件循环(Event Loop)和微任务(Microtasks)优先级是怎样的?

    事件循环先执行宏任务,期间将微任务加入队列,宏任务完成后立即清空微任务队列,微任务优先级高于宏任务。例如:同步代码(1、4)先执行,接着微任务(3)执行,最后宏任务(2)输出;多个微任务按FIFO顺序执行,包括过程中新增的微任务,如a→b→c。setTimeout即使设为0仍是宏任务,需等待下一轮。…

    2025年12月20日
    000
  • 如何构建一个命令行界面(CLI)工具使用Node.js?

    答案:使用Node.js构建CLI工具需初始化项目并配置package.json的bin字段,创建含Shebang的入口文件index.js,通过npm link测试,结合yargs等库解析参数。 构建一个命令行界面(CLI)工具使用 Node.js 并不复杂,核心是通过编写可执行的 JavaScr…

    2025年12月20日
    000
  • 解决WebKit浏览器自动填充对CSS样式的覆盖问题

    前端开发中,浏览器自动填充功能虽然方便用户,但常常会意外地覆盖我们为输入框精心设计的CSS样式,尤其是在WebKit内核的浏览器(如Chrome)中。这种现象通常表现为输入框被自动填充后,其背景颜色、文本颜色等样式突然变为浏览器默认的样式,与整体设计格格不入。即使尝试设置autocomplete=&…

    2025年12月20日
    000
  • 如何用Web Bluetooth API控制蓝牙设备?

    Web Bluetooth API 可实现网页与BLE设备通信,通过 requestDevice 选择设备并连接 GATT 服务器,读写特征值或监听数据变化,需在 HTTPS 环境下使用且仅支持 Chromium 浏览器。 Web Bluetooth API 让网页可以直接与附近的蓝牙低功耗(BLE…

    2025年12月20日
    000

发表回复

登录后才能评论
关注微信