从 Promise 结果中导出 Node 模块

2024-04-20前端开发问题
3

本文介绍了从 Promise 结果中导出 Node 模块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

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

I'm trying to rewrite a module to return a different value than before, but now it uses an async call to get that value. (with child_process if it matters). I've wrapped it in a Promise, but that's not critical to me - it can be in the original child_process callback, but the problem is I can't chain the promise to everywhere in the app because I need this to become synchronous. Here's my module:

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(/
?
/)
                 .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

显然,当需要模块时,这不起作用 - 如果我返回承诺本身,并在 require 之后使用 then - 我的下一个 module.exports 将是异步的,并且该链将继续进行.我该如何避免这种模式?

Clearly, when requiring the module, this doesn't work - and if I return the promise itself, and use then after require - my next module.exports will be async, and this chain will carry on. How do I avoid this pattern?

推荐答案

Node 中使用 require() 加载的模块是同步加载的,require 返回任何异步加载的值.它可以返回一个承诺,但该模块的用户必须将其用作:

Modules in Node that you load with require() are loaded synchronously and it is not possible for require to return any value that is loaded asynchronously. It can return a promise but then users of that module would have to use it as:

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

当然,你可以在你的模块中解析承诺,并通过添加如下内容使其在导出的对象上设置一个属性:

Of course you can have the promise resolved inside of your module and make it set a property on the exported object by adding something like this:

module.exports = { GEM_HOME: null };

和变化:

module.exports = GEM_HOME

到:

module.exports.GEM_HOME = GEM_HOME

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

In that case, every other module that uses this module as:

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

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

will have x.GEM_HOME originally set to null but it would eventually get changed to a correct value some time later. It would not be available right away though, because require() returns before the promise is settled and the value is set.

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

There is an ongoing discussion to introduce asynchronous module loading with different syntax and semantics that may be suited for your use case. It's a controversial subjects and it's worth reading all of the rationale behind it - see:

  • Node.js、TC-39 和模块 来自 IBM 的 James M Snell
  • ES6 模块互操作性 - 节点.js 增强建议
  • 为.js辩护 -Dave Herman、Yehuda Katz 和 Caridy Patio 提出的 Node.js 模块提案
  • 关于node-eps的Pull Request #3的讨论(002:ES6 模块互操作)
  • Node.js, TC-39, and Modules by James M Snell from iBM
  • ES6 Module Interoperability - Node.js Enhancement Proposals
  • In Defense of .js - A Proposal for Node.js Modules by Dave Herman, Yehuda Katz and Caridy Patio
  • Discussion on the Pull Request #3 of node-eps (002: ES6 module interop)

有关详细信息,另请参阅此答案:

See also this answer for more details:

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

这篇关于从 Promise 结果中导出 Node 模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

The End

相关推荐

js删除数组中指定元素的5种方法
在JavaScript中,我们有多种方法可以删除数组中的指定元素。以下给出了5种常见的方法并提供了相应的代码示例: 1.使用splice()方法: let array = [0, 1, 2, 3, 4, 5];let index = array.indexOf(2);if (index -1) { array.splice(index, 1);}// array = [0,...
2024-11-22 前端开发问题
182

JavaScript小数运算出现多位的解决办法
在开发JS过程中,会经常遇到两个小数相运算的情况,但是运算结果却与预期不同,调试一下发现计算结果竟然有那么长一串尾巴。如下图所示: 产生原因: JavaScript对小数运算会先转成二进制,运算完毕再转回十进制,过程中会有丢失,不过不是所有的小数间运算会...
2024-10-18 前端开发问题
301

JavaScript(js)文件字符串中丢失"\"斜线的解决方法
问题描述: 在javascript中引用js代码,然后导致反斜杠丢失,发现字符串中的所有\信息丢失。比如在js中引用input type=text onkeyup=value=value.replace(/[^\d]/g,) ,结果导致正则表达式中的\丢失。 问题原因: 该字符串含有\,javascript对字符串进行了转...
2024-10-17 前端开发问题
437

layui中table列表 增加属性 edit="date",不生效怎么办?
如果你想在 layui 的 table 列表中增加 edit=date 属性但不生效,可能是以下问题导致的: 1. 缺少日期组件的初始化 如果想在表格中使用日期组件,需要在页面中引入 layui 的日期组件,并初始化: script type="text/javascript" src="/layui/layui.js"/scrip...
2024-06-11 前端开发问题
455

Rails/Javascript:如何将 rails 变量注入(非常)简单的 javascript
Rails/Javascript: How to inject rails variables into (very) simple javascript(Rails/Javascript:如何将 rails 变量注入(非常)简单的 javascript)...
2024-04-20 前端开发问题
5

“数组中的每个孩子都应该有一个唯一的 key prop"仅在第一次呈现页面时
quot;Each child in an array should have a unique key propquot; only on first time render of page(“数组中的每个孩子都应该有一个唯一的 key prop仅在第一次呈现页面时)...
2024-04-20 前端开发问题
5