【问题标题】:How to pass variables when using multiple module exports which are dependent on the result of another?使用依赖于另一个结果的多个模块导出时如何传递变量?
【发布时间】:2017-10-19 15:05:33
【问题描述】:

我有三个文件:user.js、influencer.js 和 validate.js

在 user.js 中,我导入 ./influencer(作为 var = 影响者)和 ./validate(作为 var = validate)。

我在 user.js 中的函数:

addAccount: function(){
 return functions.database.ref('/acct/{accountID}/name/').onCreate(event => {
  var accountID = event.params.accountID;
  var name = JSON.stringify(event.data.val()).replace(/['"]+/g, '');

  console.log("New Account Added ("+accountID+")");
  console.log("Nickname: " +name);

  influencer.getIG(name);

  var data = influencer.data;

  validate.validateThis(data);
 });
}

通过fluencer.getIG(name),我将我们上面定义的名称传递给函数getIG(在influencer.js 内部)。这就像一个魅力。结果是 JSON 正文。

我现在要做的是获取这个 JSON 正文结果并将其传递给 validate 函数(在 validate.js 中)。在influencer.js中,我还添加了“exports.data = data;”。

话虽如此,我似乎无法弄清楚如何将“数据”传递给 validate.js。我记录它,它返回未定义。我在运行 validateThis(data) 之前添加了一个超时,但仍未定义。验证功能本身效果很好;我已经测试过了。但很明显,我这样做的方式不正确。

这是我的影响者.getIG 函数:

module.exports = {
 getIG: function (name) {
  var url = "https://www.instagram.com/"+name+"/?__a=1"

  console.log(url);

  request({
    url: url
  }, function (error, response, body) {

   var data = JSON.parse(body);
   console.log(data);
   exports.data = data;
  })
 }
}

如何将第二个模块的结果传递给函数中的第三个模块?我做错了什么?

【问题讨论】:

  • 听起来influencer.getIG() 是异步的,这意味着您需要一个回调或一个promise 来知道它何时完成才能访问influencer.data。您可以编辑您的问题以包含influencer.getIG 的代码吗?
  • influencer.getIG(name) 是异步的吗?如果是,则可以在检索实际数据之前调用 data =fluencer.data 。如果是这种情况,您可能必须使用回调或承诺。
  • 好的,我会用这些细节更新问题。但是,我确实添加了一个很大的超时,以确保在让 validateThis(data) 运行之前完成影响器.getIG()。不过,它仍然返回 undefined。
  • 原因是您不能从回调内部声明导出变量。当你调用 require 时,javascript 从上到下执行那段代码。当你调用 varfluencer = require('influencer) 时,它会执行influencer.js 中的代码,并在第一次结束时返回其中的所有内容。它不会等待回调结果。因此,在回调中定义的任何内容都将始终为空。添加超时将无济于事。这不是比赛条件。这是因为你不能在回调中设置变量。
  • @EugeneG 这真的很有意义。谢谢!

标签: javascript node.js google-cloud-functions


【解决方案1】:

您可以尝试将回调函数作为另一个参数传递给 getIG

您的影响者文件将如下所示。

module.exports = {
  getIG: function (name, callback) {
    var url = "https://www.instagram.com/"+name+"/?__a=1"

    request({
      url: url
    }, callback)
  }
}

您的用户文件将如下所示

addAccount: function(){
  return functions.database.ref('/acct/{accountID}/name/').onCreate(event => {
    var accountID = event.params.accountID;
    var name = JSON.stringify(event.data.val()).replace(/['"]+/g, '');

    influencer.getIG(name, function (error, response, body) {
      var data = JSON.parse(body);
      validate.validateThis(data);
    });
  });
}

使用回调将确保在调用之前检索数据。

【讨论】:

  • 这太完美了。我不太确定为什么它会完全按照它的方式工作(我是回调的新手),但这太棒了。 addAccount 的倒数第三行有一个额外的右括号,但除此之外,它就像一个魅力。谢谢!
  • 谢谢@ryangineer 我会尽力解释它。首先,从您的代码中,当您在没有回调的情况下 getIG 时,javascript 将立即运行下一个命令 var data =fluencer.data;因为 javascript 不会等待像 http get 这样的异步操作完成。那时数据还没有到达,你得到未定义。但是,在异步操作完成并且数据到达后将调用回调,因此您可以保证收到数据(如果有的话)。
【解决方案2】:

正如其他两位评论员所指出的 - 您有一个带有回调的异步函数。解决此问题的一种方法是在 user.js 文件中定义回调,并将其传递给 getIG 函数。所以你会有

user.js

<pre><code>
addAccount: function(){
return functions.database.ref('/acct/{accountID}/name/').onCreate(event => {
var accountID = event.params.accountID;
var name = JSON.stringify(event.data.val()).replace(/['"]+/g, '');

console.log("New Account Added ("+accountID+")");
console.log("Nickname: " +name);

function callback(err, res, data) {
var data = JSON.parse(body);
console.log(data);
validate.validateThis(data)
}      

influencer.getIG(name, callback);
});
}
</pre></code>

然后在另一个文件中

influencer.js



module.exports = {
getIG: function (name, callback) {
var url = "https://www.instagram.com/"+name+"/?__a=1"
request({
url: url
}, callback)
}
}

这样异步函数在影响者内部运行,然后在结果完成后回调给用户。数据现在在用户文件可以使用的范围内。

另一种(更好的)方法是使用 Promise。在这种情况下,用户代码将类似于

influencer.getIg(name).then(data => //在user.js中使用数据//)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-31
    • 2011-05-08
    • 2015-03-19
    • 1970-01-01
    • 1970-01-01
    • 2019-05-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多