从诺言结果中导出节点模块

我试图重写一个模块以返回与以前不同的值,但现在它使用异步调用来获取该值。 (如果有关系,使用child_process )。 我已经将它包装在一个Promise中,但这对我来说并不重要 - 它可以在原始的child_process回调中,但问题是我无法将承诺链接到应用程序中的任何地方,因为我需要将它变为同步。 这是我的模块:

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

显然,当需要模块时,这是行不通的 - 如果我自己返回承诺, thenrequire后使用, then我的下一个module.exports将是异步的,并且此链将继续。 我如何避免这种模式?


使用require()加载的节点中的模块将同步加载,并且require不可能返回异步加载的任何值。 它可以返回一个承诺,但该模块的用户将不得不使用它作为:

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

这是不可能的:

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

当然,你可以在你的模块内部解析promise,并通过添加如下内容来设置导出对象的属性:

module.exports = { GEM_HOME: null };

并改变:

module.exports = GEM_HOME

至:

module.exports.GEM_HOME = GEM_HOME

在这种情况下,所有其他使用此模块的模块如下所示:

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

x.GEM_HOME最初设置为null但最终会在一段时间后更改为正确的值。 但它不会立即可用,因为require()在承诺结算并设置值之前返回。

有一个正在进行的讨论,以引入异步模块加载与不同的语法和语义,可能适合您的使用情况。 这是一个有争议的主题,值得一读它背后的所有基本原理 - 请参阅:

  • Node.js,TC-39和来自iBM的James M Snell的模块
  • ES6模块互操作性 - Node.js增强建议
  • 保护.js - 由Dave Herman,Yehuda Katz和CaridyPatiño提出的关于Node.js模块的建议
  • 讨论节点-eps(002:ES6模块互操作)的请求请求#3
  • 有关更多详细信息,请参阅此答案:

  • javascript - 为什么有同步和异步模块的规范?

  • Node.js模块同步加载。

    你可以处理这个导出Promise值。

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

    和:

    #@ your app.js
    const mod = require('./module');
    
    mod.then((value => ...);
    
    链接地址: http://www.djcxy.com/p/55353.html

    上一篇: Exporting Node module from promise result

    下一篇: Return Promise result instead of Promise in Nodejs