una tutorial sincronas secuencial promesas otra funciones funcion example es6 entre ejecutar ejecucion diferencia despues convertir convert controlar coffee asincronismo asincrona anidar javascript node.js coffeescript

javascript - tutorial - js to coff



Exportar módulo de nodo desde el resultado de la promesa (2)

Los módulos Node.js se cargan sincrónicamente .

Puede lidiar con esto exportando el valor Promesa.

#@ your module.js module.exports = new Promise()

y:

#@ your app.js const mod = require(''./module''); mod.then((value => ...);

Estoy tratando de reescribir un módulo para devolver un valor diferente al anterior, pero ahora usa una llamada asincrónica para obtener ese valor. (con child_process si es importante). Lo he envuelto en una promesa, pero eso no es crítico para mí: puede estar en la devolución de llamada original de child_process, pero el problema es que no puedo encadenar la promesa en todas partes de la aplicación porque necesito que esto se sincronice. Aquí está mi módulo:

exec = require(''child_process'').exec platformHome = process.env[if process.platform is ''win32'' then ''USERPROFILE'' else ''HOME''] getExecPath = new Promise (resolve, reject) -> path = process.env.GEM_HOME if path resolve(path) else exec ''gem environment'', (err, stdout, stderr) -> unless err line = stdout.split(//r?/n/) .find((l) -> ~l.indexOf(''EXECUTABLE DIRECTORY'')) if line resolve line[line.indexOf('': '') + 2..] else reject undefined GEM_HOME = undefined getExecPath.then (path) -> GEM_HOME = path .catch -> GEM_HOME = "#{platformHome}/.gem/ruby/2.3.0" .then => module.exports = GEM_HOME // or simply return it

Claramente, cuando requiero el módulo, esto no funciona, y si devuelvo la promesa en sí y lo uso después de require , mi próximo module.exports . Las module.exports serán asíncronas, y esta cadena continuará. ¿Cómo evito este patrón?


Los módulos en el nodo que cargue con require() se cargan sincrónicamente y no es posible que require devuelva ningún valor que se cargue asincrónicamente. Puede devolver una promesa, pero los usuarios de ese módulo tendrían que usarlo como:

require(''module-name'').then(value => { // you have your value here });

No sería posible escribir:

var value = require(''module-name''); // you cannot have your value here because this line // will get evaluated before that value is available

Por supuesto, puede tener la promesa resuelta dentro de su módulo y hacer que establezca una propiedad en el objeto exportado agregando algo como esto:

module.exports = { GEM_HOME: null };

y cambiando:

module.exports = GEM_HOME

a:

module.exports.GEM_HOME = GEM_HOME

En ese caso, cualquier otro módulo que use este módulo como:

var x = require(''module-name'');

tendrá x.GEM_HOME originalmente establecido en null pero eventualmente se cambiará a un valor correcto algún tiempo después. Sin embargo, no estaría disponible de inmediato, ya que require() devuelve antes de que se cumpla la promesa y se establezca el valor.

Hay una discusión en curso para introducir la carga de módulos asíncronos con diferentes sintaxis y semánticas que pueden ser adecuadas para su caso de uso. Es un tema controvertido y vale la pena leer toda la justificación detrás de esto: ver:

Vea también esta respuesta para más detalles: