variables未定义node.js

我试图使用Node.js从API获取响应,我想清理API响应并使用结果。

所以要访问第一个API我有以下代码。

要存储和使用结果,我相信我需要存储全局的JSON输出。

但是,我无法解决如何做到这一点。

示例 –

var request = require('request'); request({url: 'https://www.car2go.com/api/v2.1/vehicles?loc=wien&oauth_consumer_key=car2gowebsite&format=json', json: true}, function(err, res, json) { if (err) { throw err; } car2go = json.placemarks; for (i = 0; i < car2go.length; i++) { delete car2go[i].address; delete car2go[i].charging; delete car2go[i].exterior; delete car2go[i].interior; delete car2go[i].smartPhoneRequired; delete car2go[i].vin car2go[i].vendor = 'car2go'; car2go[i].city = 'wien'; car2go[i].carmake = 'Smart'; car2go[i].carmodel = 'Fortwo'; } console.log(car2go); }); 

这将打印所需的结果,但是我知道这是因为我的variables是在函数中定义的。

我想访问函数之外的variables。

为了testing我是否可以做到这一点,我改变了代码 –

 var request = require('request'); request({url: 'https://www.car2go.com/api/v2.1/vehicles?loc=wien&oauth_consumer_key=car2gowebsite&format=json', json: true}, function(err, res, json) { if (err) { throw err; } car2go = json.placemarks; for (i = 0; i < car2go.length; i++) { delete car2go[i].address; delete car2go[i].charging; delete car2go[i].exterior; delete car2go[i].interior; delete car2go[i].smartPhoneRequired; delete car2go[i].vin car2go[i].vendor = 'car2go'; car2go[i].city = 'wien'; car2go[i].carmake = 'Smart'; car2go[i].carmodel = 'Fortwo'; } }); console.log(car2go); 

但是,如果我这样做,我得到

 ReferenceError: car2go is not defined 

我正在Mac OS Yosemite上运行Node v0.12.2(10.10.3)。

无可否认,我对节点非常陌生,对R,Python和PL SQL更加熟悉。

没有办法在callback函数之外获得引用,因为console.log行在调用callback函数之前运行。 您必须将callback函数传递到请求API的原因是请求库在完成请求时需要调用该函数。 同时,你的应用程序继续前进,并执行其他事情(如运行console.log行),同时等待callback函数触发。

这就是说,有很多方法来处理asynchronous代码。 我最喜欢的方式是承诺。 我使用一个名为bluebird的库来处理promise。

 var request = require('request'); var Promise = require('bluebird'); var requestP = Promise.promisify(request); 

Promise.promisify(request)的调用返回一个不Promise.promisify(request)函数的新函数,而是返回一个promise 。

 requestP({ url: 'https://www.car2go.com/api/v2.1/vehicles?loc=wien&oauth_consumer_key=car2gowebsite&format=json', json: true }) .spread(function(res, json) { var car2go = json.placemarks; for (i = 0; i < car2go.length; i++) { delete car2go[i].address; delete car2go[i].charging; delete car2go[i].exterior; delete car2go[i].interior; delete car2go[i].smartPhoneRequired; delete car2go[i].vin car2go[i].vendor = 'car2go'; car2go[i].city = 'wien'; car2go[i].carmake = 'Smart'; car2go[i].carmodel = 'Fortwo'; } }) .then(function (car2go) { console.log(car2go); }) .catch(function (err) { console.error(err); }); 

注意: .spread.spread是一样的.then除非parsing值是一个数组(这是因为传递给请求库的callback接受2个参数,这个蓝鸟会转换成一个数组,这个promise会parsing成) .spread将把数组分割回传递给你给.spread的函数的多个参数。

 Promise.resolve(['hi', 'there']).then(function (result) { console.log(result); // "['hi', 'there']" }); Promise.resolve(['hi', 'there']).spread(function (str1, str2) { console.log(str1); // 'hi' console.log(str2); // 'there' }); 

你不能将这个值一直返回到你开始asynchronous调用的同一个上下文中,但是你至less可以编写在使用promise时看起来有点同步的代码。

如果没有承诺,您将被迫从函数内的函数内部调用函数内的函数;)

响应是asynchronous的。 这意味着callback函数在将来会被调用,所以你的console.log(car2go)会在调用callback之前执行。

唯一可以可靠地使用响应的地方是在callback中或者在callback中调用的函数中。 你不能像你想要的那样使用它。 在Javascript中使用asynchronous响应需要以asynchronous方式进行编程,这意味着处理结果并仅在asynchronouscallback中使用结果。

这里是console.log()应该是的地方:

 var request = require('request'); request({url: 'https://www.car2go.com/api/v2.1/vehicles?loc=wien&oauth_consumer_key=car2gowebsite&format=json', json: true}, function (err, res, json) { if (err) { throw err; } car2go = json.placemarks; for (i = 0; i < car2go.length; i++) { delete car2go[i].address; delete car2go[i].charging; delete car2go[i].exterior; delete car2go[i].interior; delete car2go[i].smartPhoneRequired; delete car2go[i].vin car2go[i].vendor = 'car2go'; car2go[i].city = 'wien'; car2go[i].carmake = 'Smart'; car2go[i].carmodel = 'Fortwo'; } // here is where the result is available console.log(car2go); });