乐闻世界logo
搜索文章和话题

How does WebAssembly interoperate with JavaScript?

2月18日 21:49

WebAssembly and JavaScript interoperability is one of its core features, implemented through import/export mechanisms:

1. Import JavaScript Functions into WebAssembly WebAssembly can import JavaScript functions and call them internally:

javascript
// JavaScript code const importObject = { env: { log: (value) => console.log(value), add: (a, b) => a + b, currentTime: () => Date.now() } }; // Load WebAssembly module WebAssembly.instantiateStreaming(fetch('module.wasm'), importObject) .then(results => { // WebAssembly module can call imported functions });

2. Export WebAssembly Functions to JavaScript WebAssembly modules can export functions for JavaScript to call:

javascript
// After loading WebAssembly module const wasmModule = results.instance; // Call exported functions const result = wasmModule.exports.add(10, 20); console.log(result); // 30

3. Memory Sharing JavaScript and WebAssembly can share memory:

javascript
// Create shared memory const memory = new WebAssembly.Memory({ initial: 10, maximum: 100 }); // Pass memory to WebAssembly const importObject = { env: { memory: memory } }; // JavaScript can access memory const buffer = new Uint8Array(memory.buffer); buffer[0] = 42; // WebAssembly can also access the same memory

4. Data Type Conversion Data type conversion between JavaScript and WebAssembly:

JavaScriptWebAssembly
Numberf32, f64, i32, i64
BigInti64
TypedArrayMemory view
ArrayManual conversion required
javascript
// JavaScript calls WebAssembly function const result = wasmModule.exports.processData( 42, // i32 3.14, // f64 BigInt(123) // i64 ); // WebAssembly returns data const wasmResult = wasmModule.exports.getData(); const view = new Uint32Array(memory.buffer, offset, length);

5. Complex Data Structures For complex data structures, manual serialization and deserialization is required:

javascript
// Pass object function sendObjectToWasm(obj) { const jsonString = JSON.stringify(obj); const encoder = new TextEncoder(); const encoded = encoder.encode(jsonString); // Write to WebAssembly memory const buffer = new Uint8Array(memory.buffer); buffer.set(encoded, 0); // Call WebAssembly function wasmModule.exports.processObject(0, encoded.length); } // Receive object from WebAssembly function receiveObjectFromWasm(offset, length) { const buffer = new Uint8Array(memory.buffer); const slice = buffer.slice(offset, offset + length); const decoder = new TextDecoder(); const jsonString = decoder.decode(slice); return JSON.parse(jsonString); }

6. Async Operations WebAssembly itself doesn't support async, but can be implemented through JavaScript:

javascript
// WebAssembly calls async JavaScript function const importObject = { env: { fetchData: async (url) => { const response = await fetch(url); return response; } } };

7. Error Handling Handle errors between WebAssembly and JavaScript:

javascript
try { const result = wasmModule.exports.mightFail(); } catch (error) { console.error('WebAssembly error:', error); }

8. Performance Optimization

  • Reduce the number of cross-boundary calls
  • Use shared memory to avoid data copying
  • Batch process data
  • Use TypedArray for efficient binary data transfer

9. Best Practices

  • Clearly define import/export interfaces
  • Use TypeScript type definitions for type safety
  • Design data exchange formats reasonably
  • Balance performance and development experience
  • Use tools to simplify interoperability (e.g., wasm-bindgen)
标签:WebAssembly