2015-02-18 5 views
0

Я пытаюсь вернуть значение из функции внутри функции в приложении nodejs. Его всегда выходят, чтобы быть неопределенным.Возвращаемое значение вложенной функции в NodeJS

var geo = { 
    list: function(callback){ 
     var returnval; 
     gapi.getcodes(function(error, data) { 
      if (error) { 
       console.log(error); 
      } else { 
       returnval = data; 
       console.log(returnval); 
      }       
     }); 
     callback(returnval);     
     }    
} 

var geocodes = geo.list(function(){}); 
console.log("Value of geocodes: "+geocodes); 

Я знаю gapi.getcodes является асинхронной функцией и я читал на другой thread, что я должен быть проходящем функцией обратного вызова, чтобы получить возвращаемое значение. Но все же значение геокодов все еще остается неопределенным.

Когда код работает, я вижу значение, возвращенное в

console.log (ReturnVal)

. Как получить это значение для сохранения в var?

Я не уверен, что не так. Пожалуйста, помогите, я пытаюсь изучить javascript и шаблон стиля объекта.

+0

Пожалуйста, правильно отпечатайте свой код. Это очень сложно понять, что есть, когда у вас странный отступ. – jfriend00

+0

вы также можете использовать обещания. – V31

+0

жаль, что я исправил это ...: | – maths

ответ

4

geo.list() НЕ возвращает ваш ответ. Фактически, эта функция ничего не возвращает, поэтому geocodes будет просто неопределенным, как у вас было.

Таким образом, вы можете использовать его, как это потребляя результат в самой функции обратного вызова (это то, что это за):

var geo = { 
    list: function(callback){ 
     gapi.getcodes(function(error, data) { 
      if (error) { 
       callback(error); 
      } else { 
       callback(null, data); 
      }       
     }); 
     }    
} 

geo.list(function(err, geocodes){ 
    // because the result here is asynchronous, you can ONLY use it 
    // in this callback or in any function you pass it to from here 
    if (!err) { 
     console.log("Value of geocodes: "+geocodes); 
    } 
}); 

На самом деле, это может быть сделано еще проще:

var geo = { 
    list: function(callback){ 
     gapi.getcodes(callback);    
     }    
} 

geo.list(function(err, geocodes){ 
    // because the result here is asynchronous, you can ONLY use it 
    // in this callback or in any function you pass it to from here 
    if (!err) { 
     console.log("Value of geocodes: "+geocodes); 
    } 
}); 

Но с этой более простой реализацией вы можете видеть, что объект geo на самом деле не добавляет никакого значения, поскольку он просто копирует существующий API без добавления каких-либо дополнительных функций.

+0

Как сохранить его в var? Если я делаю var geocodes = geo.list (function (err, geocodes) {}); и выполните console.log (геокоды) в следующей строке, в которой говорится, что геокоды не определены. – maths

+0

@maths - прочитайте и изучите мой ответ снова. Эта функция асинхронна, и вы просто не можете делать то, что вы пытаетесь сделать. Никогда не может так поступать. Чтобы использовать асинхронные операции в Javascript, вам нужно узнать, как кодировать асинхронные результаты. Вы не можете просто программировать синхронно. Вы можете использовать результаты ТОЛЬКО в обратном вызове. – jfriend00

+0

ok, чтобы заставить асинхронные функции запускаться последовательно, мне придется делать обратные вызовы в обратных вызовах – maths

-1

Вы вызываете обратный вызов, указанный в списке за пределами обратного вызова getcodes(), и пытаетесь использовать returnval, прежде чем он будет установлен. Поскольку getcodes() является асинхронным.

Переместить callback(returnval) внутри анонимной функции, переданной в getcodes(). Как так:

var geo = { 
    list: function(callback){ 
     var returnval; 
     gapi.getcodes(function(error, data) { 
      if (error) { 
       console.log(error); 
      } else { 
       returnval = data; 
       console.log(returnval); 
       }       
      } 
      callback(returnval); // <-- here 
     ); 
     callback(returnval); // <-- instead of here 
     }    
} 

geo.list(function(geocodes) { 
    console.log("Value of geocodes: " + geocodes); 
}); 

В качестве альтернативы он может быть столь же просто, как:

var geo = { 
    list: gapi.getcodes.bind(gapi) 
}; 

geo.list(function(err, geocodes) { 
    if (!err) { 
     console.log("Value of geocodes: " + geocodes); 
    } 
}); 

лично я предпочитаю работать с обещаниями, чем обратные вызовы, вот что это будет выглядеть, как с помощью библиотеки обещания, такой как bluebird:

/** assuming bluebird is included **/ 
var gapiAsync = bluebird.promisifyAll(gapi); 

var geo = { 
    list: gapiAsync.getcodesAsync.bind(gapiAsync) 
}; 

geo.list.then(function(geocodes) { 
    console.log(geocodes); 
}); 
Смежные вопросы