0Pricing
WebAssembly (WASM) for High Performance Apps · 课时

自定义 JavaScript 回调

设计并实现可从 WebAssembly 模块内部调用的自定义 JavaScript 函数

自定义 JavaScript 回调 是 CoddyKit 上的免费 WebAssembly (WASM) for High Performance Apps 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 WebAssembly (WASM) for High Performance Apps 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 WebAssembly (WASM) for High Performance Apps 课程共包含 4 节课。

本课时的部分内容尚未翻译,以英文显示。

Calling JavaScript from WASM

Sometimes, your WebAssembly (WASM) module needs to communicate back to the JavaScript environment it's running in. This is where custom JavaScript callbacks become essential!

They allow your WASM code to trigger actions or pass data back to your web page, making your applications more interactive.

Why WASM Needs Callbacks

Imagine your WASM module performs complex calculations or processes data. Once it's done, it often needs to:

  • Update the UI: Notify JavaScript to refresh a chart or display a result.
  • Access Browser APIs: Request JavaScript to use APIs WASM can't directly access, like `localStorage` or `fetch`.
  • Log Information: Send debugging messages or status updates to the browser console.
  • Handle Events: Respond to user interactions or system events managed by JavaScript.

JavaScript Provides the Function

From the JavaScript side, setting up a callback is straightforward. You simply define a regular JavaScript function. This function will then be made available to your WebAssembly module during its initialization.

Think of it as giving your WASM module a direct line to call back into your JavaScript application when needed.

WASM Declares the Import

On the WebAssembly side (e.g., in Rust or C/C++), you need to declare that your module expects to import a function from its host environment (JavaScript).

  • In Rust, you use the #[wasm_bindgen] attribute with an extern "C" block.
  • This declaration specifies the function's name and its expected signature (parameters and return type).
  • It tells the WASM compiler that this function call will be resolved externally by JavaScript.

Rust Code: Importing JavaScript

Let's look at a Rust example. We'll import a JavaScript function named logMessageFromWasm. When Rust calls this, the corresponding JS function will execute.

/* lib.rs */
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
extern "C" {
    // Imports a JS function named 'logMessageFromWasm'
    // It takes a string and returns nothing.
    #[wasm_bindgen(js_name = logMessageFromWasm)]
    fn log_message_from_wasm(s: &str);
}

#[wasm_bindgen]
pub fn call_js_log() {
    log_message_from_wasm("Hello from Rust!");
}

Running the Callback (JS + Rust)

To run the Rust code from the previous scene, we compile it to a .wasm module and use wasm-bindgen's glue code. Then, we define our JavaScript callback and load the WASM.

Check your browser's developer console after running!

<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
    <title>WASM Callback Demo</title>
</head>
<body>
    <h1>Check console for WASM message!</h1>
    <script type="module">
        // Assuming 'pkg/rust_wasm_module.js' is generated by wasm-pack
        import init, { call_js_log } from './pkg/rust_wasm_module.js';

        // Define the JavaScript function that WASM will call
        window.logMessageFromWasm = (message) => {
            console.log("JS received:", message);
        };

        async function run() {
            await init(); // Initialize the WASM module
            call_js_log(); // Call the Rust function, which calls JS
        }

        run();
    </script>
</body>
</html>

Passing Data to Callbacks

Callbacks are not just for simple notifications; they can also pass data from your WebAssembly module back to JavaScript. This is crucial for returning results or providing context.

  • Primitive Types: Numbers (integers, floats) and booleans are passed directly.
  • Strings: With wasm-bindgen, Rust strings (`&str`) are efficiently converted to JavaScript strings.
  • Complex Objects: For more intricate data structures, `wasm-bindgen` provides mechanisms for seamless serialization and deserialization.

Callback with Arguments (Rust)

Let's enhance our Rust example to pass a number back to JavaScript. The `log_number_from_wasm` function is imported, expecting an integer argument.

Our Rust function `calculate_and_log` will perform a sum and then pass the result to this JS callback.

/* lib.rs */
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
extern "C" {
    // Imports a JS function that takes an i32 number
    #[wasm_bindgen(js_name = logNumberFromWasm)]
    fn log_number_from_wasm(num: i32);
}

#[wasm_bindgen]
pub fn calculate_and_log(a: i32, b: i32) {
    let result = a + b;
    log_number_from_wasm(result); // Call JS with the calculated result
}

Running Callback with Arguments

Here's the JavaScript setup for the previous Rust example. Notice how the `window.logNumberFromWasm` function now accepts a numeric argument, which it then prints to the console.

<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
    <title>WASM Callback Args Demo</title>
</head>
<body>
    <h1>Check console for calculated result!</h1>
    <script type="module">
        import init, { calculate_and_log } from './pkg/rust_wasm_module.js';

        // This JS function will receive a number from WASM
        window.logNumberFromWasm = (number) => {
            console.log("JS received result:", number);
        };

        async function run() {
            await init();
            calculate_and_log(10, 20); // Call Rust with arguments 10 and 20
        }

        run();
    </script>
</body>
</html>

Common Callback Scenarios

Custom callbacks are incredibly versatile and enable WASM to integrate smoothly with the browser's environment. Some common use cases include:

  • User Interface Updates: Notifying JS to update elements after a WASM computation is complete.
  • Browser API Access: Requesting JS to use `localStorage`, `fetch`, or directly manipulate the DOM.
  • Event Handling: Allowing WASM to react to user input or browser events processed by JS.
  • Logging and Debugging: Sending detailed messages to the browser console from within WASM for monitoring.

Quick Check on Callbacks

Understanding how to declare and use imported functions is key to effective WASM-JS communication.

Recap: Custom JS Callbacks

You've learned how to enable your WebAssembly modules to call back into JavaScript!

  • WASM modules can import and call JavaScript functions.
  • wasm-bindgen simplifies this process in Rust, allowing type-safe data exchange.
  • Callbacks are crucial for UI updates, accessing browser APIs, and logging from WASM.

This powerful pattern makes WASM applications more dynamic and integrated with the web environment. Keep experimenting!

常见问题解答

「自定义 JavaScript 回调」课时是免费的吗?

是的 — 「自定义 JavaScript 回调」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 WebAssembly (WASM) for High Performance Apps 课程的其余内容,请升级到 CoddyKit PRO。 WebAssembly (WASM) for High Performance Apps 课程共包含 4 节课。

「自定义 JavaScript 回调」这节课中我会学到什么?

设计并实现可从 WebAssembly 模块内部调用的自定义 JavaScript 函数 你通过在浏览器中直接运行的动手代码来练习 WebAssembly (WASM) for High Performance Apps,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 WebAssembly (WASM) for High Performance Apps 需要有经验吗?

无需任何先前经验。CoddyKit 上的 WebAssembly (WASM) for High Performance Apps 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「自定义 JavaScript 回调」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 WebAssembly (WASM) for High Performance Apps 课中编写并运行代码吗?

能。每节 WebAssembly (WASM) for High Performance Apps 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 使用 WASM 执行异步操作
  2. 自定义 JavaScript 回调
  3. 错误处理与异常
  4. 跨 JS/WASM 边界共享内存与类型化数组
← 返回 WebAssembly (WASM) for High Performance Apps