在NodeJS中返回嵌套函数的值

时间:2015-02-18 05:09:19

标签: javascript node.js

我正在尝试从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和对象样式模式。

2 个答案:

答案 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}}