【问题标题】:Node JS How to access global variable from Callback function of a function?Node JS如何从函数的回调函数访问全局变量?
【发布时间】:2017-02-11 08:32:32
【问题描述】:

我正在使用 NodeJS 来捕获事件。所有的调用都将进入 getme 函数。从这个函数中,我调用 getUserLocation() 函数,该函数根据 ip 返回 Geolocation。如何根据这些值更新全局变量?

var getClientAddress = function (req) {
return (req.get('x-forwarded-for') || '').split(',')[0]  || req.connection.remoteAddress;
}

var getClientLocation = function (ipaddress, callback) {
    freegeoip.getLocation(ipaddress, function(err, location) {
        if (err) throw err;
        return callback(location);
    });
}

var store = [{'hello': 'world', 'country': 'India', 'City': 'Indupur'}];

for (eve=0;eve<store.length;eve++){
if(!store[eve].lat){
        clientIp = getClientAddress(req);
        getClientLocation("XXX:XX:XX:XXX", function(resp) {
            console.log(resp);
            store[eve].country = store[eve].country || resp.country_name;
            store[eve].region = store[eve].region || resp.region_name;
            store[eve].city = store[eve].city || resp.city;
            store[eve].lat = store[eve].lat || resp.latitude;
            store[eve].lng =  store[eve].lng || resp.longitude;
        });

    }

但商店无法访问。它是未定义的。如何更新商店?

实际代码: 这是实际代码:

https://github.com/Gowtham95india/CapVengine/blob/master/server.js

这是错误信息:

Server started! At http://localhost:8080
Redis started! Ready to perform
{ e: '[{"device_id":"dsfkdjf-dsfdls-fejfskj-e2oiej2j3jf","user_id":2124,"email":"gowtham95india@gmail.com","event_properties":{"utm_source":"HelloWorld"}, "lat":""}]',
  v: 2 }
2017-02-11T09:02:10.838Z


{ ip: '121.244.122.142',
  country_code: 'IN',
  country_name: 'India',
  region_code: 'MH',
  region_name: 'Maharashtra',
  city: 'Phursungi',
  zip_code: '412308',
  time_zone: 'Asia/Kolkata',
  latitude: 18.4667,
  longitude: 73.9833,
  metro_code: 0 }
/Users/GowthamSai/Documents/repo/capeve/server.js:111
                store[eve].country = store[eve].country || resp.country_name;
                                               ^

TypeError: Cannot read property 'country' of undefined
    at /Users/GowthamSai/Documents/repo/capeve/server.js:111:48
    at /Users/GowthamSai/Documents/repo/capeve/server.js:36:16
    at Request._callback (/Users/GowthamSai/Documents/repo/capeve/node_modules/node-freegeoip/lib/freegeoip.js:25:16)
    at Request.self.callback (/Users/GowthamSai/Documents/repo/capeve/node_modules/request/request.js:187:22)
    at emitTwo (events.js:106:13)
    at Request.emit (events.js:191:7)
    at Request.<anonymous> (/Users/GowthamSai/Documents/repo/capeve/node_modules/request/request.js:1048:10)
    at emitOne (events.js:96:13)
    at Request.emit (events.js:188:7)
    at IncomingMessage.<anonymous> (/Users/GowthamSai/Documents/repo/capeve/node_modules/request/request.js:969:12)
    at emitNone (events.js:91:20)
    at IncomingMessage.emit (events.js:185:7)
    at endReadableNT (_stream_readable.js:974:12)
    at _combinedTickCallback (internal/process/next_tick.js:74:11)
    at process._tickCallback (internal/process/next_tick.js:98:9)

【问题讨论】:

  • 一般在javascript中定义一个全局变量,在函数声明时不要使用关键字var。尝试在 store 变量声明期间省略关键字 var
  • 您到底看到了哪个错误?
  • @SiddharthSrinivasan - 这是一个可怕的建议。 Javascript 中的所有变量都应该显式声明。您应该只在所需范围内声明它们。隐式或意外全局变量是一个可怕的想法,事实上,在严格模式下运行时会出错(安全的编程方式)。
  • 添加';'在getClientAddressgetClientLocation 的声明之后和store 声明之前。
  • store 应该可以正常访问。为什么你认为是undefined

标签: javascript node.js scope asynccallback


【解决方案1】:

您的问题不在于访问store。该全局变量已定义。

你的问题是访问store[eve],因为你从来没有定义过

您直接尝试读取store[eve].lat,而无需为store[eve] 分配任何内容(例如使用store[eve] = store[eve] || {})。


您还有一些其他问题,这是该问题的根本原因,解释如下:

【讨论】:

  • 如果我没记错的话,在 for 循环 eve 中保存了索引位置的值。因此,store[eve] 将是第一次迭代时 store 的第一个元素。如果我错了,请纠正我。
  • @7H3IN5ID3R — 你错了。请参阅答案末尾的两个链接。 eve 将在回调触发之前更新。
  • 是的,你是对的。 eve 值变为 1. store[1] 这显然是未定义的。感谢您指出错误。在这种情况下,纠正这个问题的好方法是什么?
  • 我使用 forEach 解决了这个问题。还有一个疑问,我无法在 getRedisResult 回调中访问 redis_result 。我正在分配它,但除此之外仍然是空的。
猜你喜欢
  • 2018-10-09
  • 1970-01-01
  • 1970-01-01
  • 2017-06-09
  • 1970-01-01
  • 1970-01-01
  • 2021-05-17
  • 1970-01-01
  • 2018-04-06
相关资源
最近更新 更多