2017-01-01 88 views
-1

我有一个这样的模块。NodeJS需要范围变量

somemodule.js

module.exports = { 
    val: null, 
    get: function() { 
    finddata('/', function(resp) { 
     this.val = resp 
    } 
    } 
} 

,被称为像这样:

var x = require('somemodule'); 
x.get(); 
x.get(); 

一号get调用后,该x.val没有被设置。试过这个以及哪个不起作用:

module.exports = { 
    val: null, 
    get: function() { 
    var that = this; 
    finddata('/', function(resp) { 
     that.val = resp 
    } 
    } 
} 

如何设置x.val?

+0

finddata是异步吗?你确定它的回调被称为? –

+0

它是异步的,它被称为 –

+2

第一个片段不会按预期工作,因为回调中的this关键字意味着函数本身,而不是您想要导出的整个对象。我没有看到第二种方法有什么问题,所以你如何检查'x.val'是否被设置?你可以做'console.log(那)'看看它是否被设置? –

回答

2

您的finddata异步运行,它会被调用并立即返回以继续下一行执行。那一刻它不确定回调是否被执行。一旦执行回调,则只设置值。要确保设置值,然后获取值后,可以使用承诺。

我刚才已经采取了两个样本文件a.js和b.js解释它是如何工作的

a.js

module.exports = { 
     val:null, 
     get:function(){ 
      var that = this; 
      return new Promise(function(resolve, reject) { 
       that.finddata('/', function(resp){ 
        that.val = resp; 
        resolve() 
       }) 
      }); 

     }, 
     finddata :function(path,callback){ 
      setTimeout(function() { 
      console.log("Lets wait for some time"); 
      callback(10); 
      }, 100) 
     } 
    } 

b.js

var x = require('./a'); 
x.get().then(function(){ 
     console.log(x.val) 
}); 

输出

Lets wait for some time 

10 
+1

请提供您的解决方案的解释,以便其他人可以学习。这会让你的答案更有用。 –

+0

谢谢Felix,我也向你学习@ FelixKling – Sumeet

2

首先,问题不在于要求什么,它与范围无关。实际情况是,正如其他人所述,finddata是异步功能,这意味着您不知道将来的回调function (resp) {...}将在什么时间调用,并且val不是null。要解决此问题,您需要将附加回调传递给get函数,或者返回get函数的承诺。更清洁的做法是从get函数返回Promise。

x.get() 
.then(() => { 
    // val is ready 
}) 

x.get(() => { 
    // val is ready 
}) 

还有一个问题,你必须是你没有考虑到,如果有什么finddata调用你的回调有错误?有类似的东西:

finddata('/', function(resp){ 
    that.val = resp 
} 

真的是你不想拥有的东西。使用您拥有的代码,如果finddataerror调用您的回调,则val将等于该错误,否则将等于null,如果finddata符合节点最佳实践以调用null回调(如果没有错误),则返回作为cb(null, data)

除此之外,你正在尝试做什么?是否需要使用val事件来暴露模块? get函数意味着从应用程序定期调用?如果是的话,为什么要引入新的模块,只需拨打finddata这是我猜模块本身已经。