2013-09-18 3 views
6

Я использую модуль clouddns для импорта ~ 800 доменных имен в учетную запись Rackspace. Я получаю сообщение об ошибке сказав следующееПеременная Node.js 'undefined' при передаче функции

TypeError: Cannot call method 'forEach' of undefined 
at _wrapDomains (/home/duet/www/git/node-rackspace/node_modules/clouddns/lib/clouddns/core.js:146:17) 
at /home/duet/www/git/node-rackspace/node_modules/clouddns/lib/clouddns/core.js:209:14 
at Request._callback (/home/duet/www/git/node-rackspace/node_modules/clouddns/lib/clouddns/common.js:170:5) 
at Request.self.callback (/home/duet/www/git/node-rackspace/node_modules/clouddns/node_modules/request/main.js:120:22) 
at Request.EventEmitter.emit (events.js:98:17) 
at Request.<anonymous> (/home/duet/www/git/node-rackspace/node_modules/clouddns/node_modules/request/main.js:555:16) 
at Request.EventEmitter.emit (events.js:95:17) 
at IncomingMessage.<anonymous> (/home/duet/www/git/node-rackspace/node_modules/clouddns/node_modules/request/main.js:517:14) 
at IncomingMessage.EventEmitter.emit (events.js:117:20) 
at _stream_readable.js:920:16 

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

CloudDNS.prototype.getDomains = function getDomains(options, callback) { 
    var args = Array.prototype.slice.call(arguments), 
     callback = args[args.length - 1]; 

    if (typeof callback !== 'function') { 
     throw new Error("This method requires a callback"); 
    } 

    var self = this; 
    var reqOpts = { 
     method: 'GET', 
     uri: this.dnsUrl('domains'), 
     client: this 
    } 

    if ((arguments.length > 1) && (typeof arguments[0] === 'object')) { 
     reqOpts.params = { 
      name: args[0] 
     } 
    } 

    this.rackspace(reqOpts, callback, function(body) { 
     var result = JSON.parse(body); 
     console.log(result.domains); //good here, it's an array and I can even forEach on it! 
     self._wrapDomains(result.domains, callback); //undefined wtf? 
     console.log(result.domains); //same as before, works brilliantly 
    }); 
}; 

CloudDNS.prototype._wrapDomains = function _wrapDomains(domainArray, callback) { 
    var self = this; 
    var results = []; 

    console.log(domainArray); //reports undefined 

    domainArray.forEach(function(domain) { 
     results.push(new(clouddns.Domain)(self, domain)); 
    }); 

    return callback(null, results); 
} 

Я weirded тем фактом, что result.domains определяется до и после того, как метод вызывается, но внутри этого метода он является «неопределенным». Может ли кто-нибудь пролить свет на то, почему это происходит?

+0

Я попытался воспроизвести проблему с минимальным примером, но он работает, как и ожидалось. Не стесняйтесь обманывать себя по адресу http://jsfiddle.net/cc7KJ/ – Amberlamps

+2

Возможно, что метод _wrapDomains переопределяется и не передает данные, как ожидалось. Чтобы проверить, что в обратном вызове 'this.rackspace' после регистрации' result.domains' вы можете 'console.log (self._wrapDomains.toString());' Итак, чтобы увидеть исходный код функции, и если он отличается из фактического '_wrapDomains' ниже, то он переопределяется. – moka

+0

Что еще более странно, так это то, что обратный вызов от вызывающего метода (CloudDns.getDomains()) фактически отправляет правильные данные. Поскольку это одноразовая вещь, и, похоже, она работает - я только что завернул весь метод domainArray.forEach() в try/catch, чтобы он не останавливал скрипт. –

ответ

1

Я просто проверяю исходный код на github. Если вы посмотрите на вторую строку в вашей трассировке стека, то это at /home/duet/www/git/node-rackspace/node_modules/clouddns/lib/clouddns/core.js:209:14

Итак, _wrapDomains получает вызов в конце файла в методе createDomain (строка 209). Если вы исследуете там, вы узнаете, почему он вызывает его с нулевыми значениями.

Смежные вопросы