2017-01-01 3 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(); 

После 1-го ПОЛУЧИТЬ вызова, это x.val не создаются. Пробовал это также и не работает:

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

Как установить x.val?

+0

Является ли 'finddata' асинхронным? Вы уверены, что его callback был вызван? –

+0

Это асинхронно, и он называется –

+2

. Первый фрагмент не будет работать так, как предполагалось, потому что ключевое слово this this в обратном вызове означает сама функция, а не весь объект, который вы хотите экспортировать. Я не вижу ничего плохого во втором подходе, так как вы проверили, установлен ли «x.val» или нет? Можете ли вы выполнить 'console.log (that)', чтобы узнать, установлен ли он? –

ответ

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

Спасибо Феликс, я также учился у вас @ FelixKling – Sumeet

2

Прежде всего проблема заключается не в необходимости чего-то, а в отношении объема. То, что на самом деле происходит, как уже указывалось другими, finddata - это асинхронная функция, означающая, что вы не знаете, в какое время в будущем будет вызван обратный вызов function (resp) {...}, и когда val будет чем-то отличным от null. Чтобы решить эту проблему, вам необходимо либо пройти дополнительный обратный вызов до функции get, либо вернуть обещание от функции get. Более чистый подход состоял бы в том, чтобы вернуть Promise с функции get.

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

или

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

Другая проблема, которая у вас есть, что вы не принимая во внимание то, что если finddata вызывает ваш обратный вызов с ошибкой? Имея что-то вроде:

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

Это действительно то, чего вы не хотите иметь. С кодом, который у вас есть, если finddata вызывает ваш обратный вызов с помощью error, то val будет равен этой ошибке, в противном случае он будет равен null, если finddata соответствует лучшим методам узлов для вызова обратного вызова с null, если ошибок не было, таких как cb(null, data).

Кроме того, что вы пытаетесь сделать? Есть ли необходимость в экспонировании модуля с val? Функция get предназначена для регулярного вызова из приложения? Если да, то зачем вводить новый модуль, просто позвоните finddata, который я уже сам думаю.

Смежные вопросы