Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

442
Views
¿Cómo llamar a una función de importación de JavaScript asíncrona desde WebAssembly (Rust) en un entorno node.js?

Consideremos un objeto de importación de ejemplo que se ve así:

 const importObject = { exampleAsyncImportFunction: async () => fs.readFile("./someExampleFile.txt", "utf-8") // returns Promise<String> };

Quiero usarlo en mi módulo WASM escrito en óxido similar a este:

 #[wasm_bindgen] extern "C" { pub async fn exampleAsyncImportFunction() -> JsValue; // Importing the JS-Function } #[wasm_bindgen] pub async fn exampleExportFunction() -> Result<JsValue, JsValue> { let theJSPromise = exampleAsyncImportFunction(); // Call the async import function let promiseResult = theJSPromise.await; // Execute the async import function // Do sth with the result OK(JsValue::UNDEFINED) }

Desafortunadamente, esto conduce a un error inalcanzable. Curiosamente, funciona cuando la función JavaScript devuelve, por ejemplo, una cadena, como esta:

 const importObject = { exampleAsyncImportFunction: async () => "Some dummy content" // returns Promise<String> as well };

Pero, por supuesto, una función de importación asíncrona debería realizar algunas tareas asíncronas reales; de lo contrario, sería mejor usar una función síncrona.

Traté de investigar un poco y encontré 'js_sys::Promise' que representa una JS-Promise en Rust, y 'wasm_bindgen_futures::JsFuture' que permite convertir de alguna manera una JS-Promise en una Rust-Future. Pero no entiendo si/cómo estos tipos pueden ayudar con el problema y también cómo deben usarse en general en este contexto.

También parece que el tipo de retorno de JS-Import-Function, que es 'JsValue' por declaración, de alguna manera implementa el 'Future'-Trait. Entiendo que por eso es posible 'esperar' el resultado. Pero estoy confundido, ¿cuál es el tipo subyacente real (JsFuture, Promise, algo más...).

Espero que alguien pueda ayudarme con esto, resolviendo el problema real, pero también explicando un poco las relaciones entre todos los tipos (especialmente con respecto a JsValue).

¡Gracias de antemano!

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

Encontré la solución yo mismo, y como parece que no hay buena información en otros lugares de Internet, quiero compartir mi solución con cualquiera que tenga problemas similares.

Para importar la función JavaScript, es importante actuar como si la función fuera síncrona, aunque es asíncrona. La razón de esto es que las funciones asíncronas en Rust solo se ejecutan cuando se usa un ejecutor o una espera. Por lo tanto, la función async-JS, que bajo el capó es una función síncrona que devuelve una Promesa, se puede usar de forma síncrona. La promesa devuelta se puede llamar explícitamente.

La sección de importación tendrá el siguiente aspecto:

 #[wasm_bindgen(module = "/some/file.js")] extern "C" { pub fn exampleAsyncImportFunction() -> JsValue; // JsValue <==> Promise // Instead of: // pub async fn exampleAsyncImportFunction() -> Result<JsValue, JsValue> }

Para consumir la función de importación, Promise como JsValue debe convertirse en js_sys::Promise y luego en wasm_bindgen_futures::JsFuture. Después de eso, se puede esperar como se esperaba.

La función de exportación de muestra de las preguntas originales se verá así:

 #[wasm_bindgen] pub async fn exampleExportFunction() { // Get a reference to the import function as a 'JsValue' let promiseAsJsValue = exampleAsyncImportFunction(); // No execution, yet // Convert 'JsValue' to 'js_sys::Promise', which is a proxy-type for JS-Promises let promise = js_sys::Promise::from(promiseAsJsValue); // Convert 'js_sys::Promise' to 'wasm_bindgen_future::JsFuture' let future = wasm_bindgen_future::JsFuture::from(promise); // Actually execute the Promise/Future let result: Result<JsValue, JsValue> = future.await; // Interpret the result if let Ok(content) = result { // do sth with the content } }

Espero que este enfoque, específicamente la transformación de JsValue a JsFuture, ayude a algunos de ustedes, ya que los documentos oficiales no cubren ese caso de uso, sino solo la instanciación manual de un js_sys::Promise (por ejemplo, Promise::resolve( &"foo".into()) ) o usando web_sys::window::fetch().

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!