
本文档旨在指导开发者如何使用 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
微信扫一扫
支付宝扫一扫