Tenía mi módulo personalizado con el siguiente código:
module.exports.PrintNearestStore = async function PrintNearestStore(session, lat, lon) { ... }
Funcionó bien si llamé a la función fuera de mi módulo, sin embargo, si llamé adentro, recibí un error mientras ejecutaba:
(nodo: 24372) UnhandledPromiseRejectionWarning: Rechazo de promesa no manejado (id de rechazo: 1): ReferenceError: PrintNearestStore no está definido
Cuando cambié la sintaxis a:
module.exports.PrintNearestStore = PrintNearestStore; var PrintNearestStore = async function(session, lat, lon) { }
Comenzó a funcionar bien dentro del módulo, pero falla fuera del módulo; recibí el error:
(nodo: 32422) UnhandledPromiseRejectionWarning: Rechazo de promesa no manejado (id de rechazo: 1): TypeError: mymodule.PrintNearestStore no es una función
Así que he cambiado el código a:
module.exports.PrintNearestStore = async function(session, lat, lon) { await PrintNearestStore(session, lat, lon); } var PrintNearestStore = async function(session, lat, lon) { ... }
Y ahora funciona en todos los casos: por dentro y por fuera. Sin embargo, ¿quieres entender la semántica y si hay una forma más hermosa y más corta de escribirla? ¿Cómo definir y usar correctamente la función asíncrona tanto: dentro como fuera del módulo (exportaciones)?
Esto realmente no tiene nada que ver con las funciones asíncronas especialmente. Si desea llamar a una función internamente y exportarla, primero defínala y luego expórtela.
async function doStuff() { // ... } // doStuff is defined inside the module so we can call it wherever we want // Export it to make it available outside module.exports.doStuff = doStuff;
Explicación de los problemas con sus intentos:
module.exports.PrintNearestStore = async function PrintNearestStore(session, lat, lon) { ... }
Esto no define una función en el módulo. La definición de función es una expresión de función. El nombre de una expresión de función solo crea una variable dentro de la función misma. Ejemplo más simple:
var foo = function bar() { console.log(typeof bar); // 'function' - works }; foo(); console.log(typeof foo); // 'function' - works console.log(typeof bar); // 'undefined' - there is no such variable `bar`
Ver también Expresiones de funciones con nombre desmitificadas . Por supuesto, podría referirse a la función si hiciera referencia a module.exports.PrintNearestStore
en todas partes.
module.exports.PrintNearestStore = PrintNearestStore; var PrintNearestStore = async function(session, lat, lon) { }
Esto está casi bien. El problema es que el valor de PrintNearestStore
no está undefined
cuando lo asigna a module.exports.PrintNearestStore
. El orden de ejecución es:
var PrintNearestStore; // `undefined` by default // still `undefined`, hence `module.exports.PrintNearestStore` is `undefined` module.exports.PrintNearestStore = PrintNearestStore; PrintNearestStore = async function(session, lat, lon) {} // now has a function as value, but it's too late
Ejemplo más simple:
var foo = bar; console.log(foo, bar); // logs `undefined`, `undefined` because `bar` is `undefined` var bar = 21; console.log(foo, bar); // logs `undefined`, `21`
Si cambiaste el orden, funcionaría como se esperaba.
module.exports.PrintNearestStore = async function(session, lat, lon) { await PrintNearestStore(session, lat, lon); } var PrintNearestStore = async function(session, lat, lon) { ... }
Esto funciona porque cuando se ejecuta la función asignada a module.exports.PrintNearestStore
, PrintNearestStore
tiene la función como su valor.
Ejemplo más simple:
var foo = function() { console.log(bar); }; foo(); // logs `undefined` var bar = 21; foo(); // logs `21`
Error con el primer caso: PrintNearestStore
- Expresión de función, por lo que este nombre no está disponible fuera.
error con el segundo caso: usar variable, en lugar de declaración de función. En este caso, la declaración de la variable PrintNearestStore se eleva, por lo que puede usar este nombre antes de la línea var PrintNearestStore = ...
, pero en este caso el valor no estaría definido .
Entonces, la solución más simple cambia la segunda variante de esta manera:
module.exports.PrintNearestStore = PrintNearestStore; async function PrintNearestStore(session, lat, lon) { }
una alternativa sería exportar así. // foo.js
export async function foo(){ console.log('I am greatest of all.'); // for the person who reads it, just say it. }
luego utilícelo en otros scripts como
import { foo } from './foo' foo();