我正在尝试从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 :(得分:4)
geo.list()
不会回复你的答案。事实上,该函数不会返回任何内容,因此geocodes
将不会像您所拥有的那样被定义。
相反,需要修改geo.list()
,因此它将data
值作为参数传递给回调,因为只有在将来的某个时间调用异步getcodes回调时才会实际获得数据。 / p>
所以,您可以通过在回调函数本身中使用结果(这就是它的用途)来像这样使用它:
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。 / p>
答案 1 :(得分:-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);
}
});
或者它可以简单如下:
/** assuming bluebird is included **/
var gapiAsync = bluebird.promisifyAll(gapi);
var geo = {
list: gapiAsync.getcodesAsync.bind(gapiAsync)
};
geo.list.then(function(geocodes) {
console.log(geocodes);
});
我个人更喜欢使用承诺而不是回调,这就是使用承诺库,例如bluebird:
{{1}}