除非我删除看似无关的要求,否则不会导入文件

时间:2015-10-29 16:02:56

标签: javascript node.js

给定文件server.js以及这些内容:

'use strict';
const values      = require('../valueData/values');
const insertValue = require('../valueData/insertValue');
insertValue.insertRecord(null, null, null, null, null);

档案values.js

'use strict';
const entity = require('../masterData/entity.js');
console.log('inside values.js');

档案insertValue.js

'use strict';
const cache = require('../components/cache.js');
function insertRecord(id, value, valueTimestamp, geolocation, callback) {
    cache.getCached(id, function (error, entity) {

    });
}
module.exports = {
    insertRecord,
}

档案cache.js

'use strict';
const entity = require('../masterData/entity.js'); 
const customer = require('../masterData/customer.js');
console.log('CUSTOMER');
console.log(customer);
console.log('ENTITY');
console.log(entity);
function getCached(id, callback) {
};
module.exports = {
  getCached,
}

当我执行此操作时,输出将为:

CUSTOMER
{ 
  getCustomerInfoFromDB: [Function: getCustomerInfoFromDB],
}
ENTITY
{ 
}

本质上:entity对象不包含任何功能(是的,它们是通过modules.export导出的。

但是当我在values.js中评论导入时,我得到了预期的输出:

CUSTOMER
{ 
  getCustomerInfoFromDB: [Function: getCustomerInfoFromDB],
}
ENTITY
{ 
  getEntityByID: [Function: getEntityByID],
}

什么可能导致这种行为? entity.jscustomer.js都具有相同的导入。注意问题也是"修复"当我在values中评论server.js导入时,但这不是解决方案。这一切似乎都指向values.js中的导入以某种方式混淆了事实。

1 个答案:

答案 0 :(得分:4)

你还没有把entity.js放在这里(我们在聊天室里谈论你已经把它链接起来了),但你把它链接到聊天室(我不会去除非我允许,否则将其发布在此处,但它表明您在要求中有一个循环引用。

在NodeJS中,循环引用不会导致错误。相反,你会得到一些更微妙的东西。基本上,每当你require一个包时,它只需要一次,代码只执行一次。这意味着当你有这样的代码时......

// alice.js
var bob = require('./bob.js')
bob.say()
module.exports = {
  say: function () { console.log('hello bob') }
}

// bob.js
var alice = require('./alice.js')
alice.say()
module.exports = {
  say: function () { console.log('hello alice!')
}

这一系列事件将会发生:

  1. Alice将由核心口译员require组成。
  2. Alice会要求Bob。
  3. Bob将要求Alice。
  4. Alice已经缓存,但在设置module.exports之前她退出了。这意味着她的module.exports将默认为{}
  5. Bob尝试调用Alice module.exports.sayundefined,并收到错误,停止执行。
  6. 这似乎是您的代码中发生的事情:当您需要entity.js时,这需要cache.js,然后再次需要entity.js并尝试立即使用其中一项功能。此函数为undefined,因为我上面列出的行为,以及代码错误。

    但是,在insertValues中,您需要entity.js,而是cache.js。执行cache.js时,需要entity.js,但entity.js不使用任何cache.js&#39}。立即起作用,所以没有错误。 entity.js成功设置module.exports并缓存调用它们没问题。

    TLDR:循环引用是邪恶的!仅仅因为Node并没有告诉你使用它们并不意味着你应该这样做。将循环行为移动到第三级文件。如果你试图解决这个问题,它会让你头痛。