2017-01-01 87 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這是我猜模塊本身已經。