nodejs 循环依赖及引用中无法使用对象方法或属性

相信很多使用 nodejs 有朋友都会遇到了循环依赖的问题,它的原理是什么?我们怎样在日常开发中规避掉这样的问题?

场景重现

one.js

console.log('one init');
const two = require('./two');
var exp = module.exports = {};
console.log('one exports');
function start() {
    console.log('one start');
    two.start();
}
function load() {
    console.log('one load');
}
exp.start = start;
exp.load = load;

two.js

console.log('two init');
const one = require('./one');
var exp = module.exports = {};

function start() {
    console.log('two start');
    one.load();
}

exp.start = start;

main.js

const one = require('./one')

one.start();

输出结果

$ node main.js
one init
two init
one {}
one exports
one start
two start
E:\source\nodejs\test\loop_require\two.js:8
    one.load();
        ^

TypeError: one.load is not a function
    at Object.start (E:\source\nodejs\test\loop_require\two.js:8:9)
    at Object.start (E:\source\nodejs\test\loop_require\one.js:7:9)
    at Object.<anonymous> (E:\source\nodejs\test\loop_require\main.js:3:5)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.runMain (module.js:604:10)
    at run (bootstrap_node.js:394:7)

上面的场景其实有一个循环依赖和 module.exports 的问题,首先我们肯定下造成上面的远行异常本身不是循环依赖造成的,而是我们代码中对 exports 使用异常造成的

module.exports 是什么?

相信细心的朋友应该知道,如果你直接 require 一个空的模块的话,它是一个空对象,上面的场景中 two.js 引用 one.js 此时的对象为 {}one.js 中对 exports 对象进行了重新指向,此时 two.js 中引用到的对象和 one.js 后续重新生成的 exports 对象已经不是一个对象了,所以在 two.js 中使用 one.start() 中的方法时提示 TypeError: one.load is not a function

官方文档中对 exports 的描述

如何解决

1. 把模块的方法直接绑定到 module.exports 对象上(如果出现重复依赖时尤其要这样做)

module.exports.start = function() {
    // do something
}

exports.run = function() {
    // do something
}

2. 在方法使用时再引用(不建议这样使用)

上面场景中的 two.js 可以有如下写法:

console.log('two init');
const one = require('./one');
var exp = module.exports = {};

function start() {
    console.log('two start');
    require('./one').load();
}

exp.start = start;

nodejs 本身对循环依赖的处理是很合理的,出现问题也都是我们逻辑处理上的问题,希望上面的分析和解决方案可以帮助到还被困扰中的你。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,667评论 5 472
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,361评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,700评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,027评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,988评论 5 361
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,230评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,705评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,366评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,496评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,405评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,453评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,126评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,725评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,803评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,015评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,514评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,111评论 2 341

推荐阅读更多精彩内容