CommonJS singelton模块中的循环依赖

我想知道是否和如何以下是可能的:

CommonJS环境,用于节点和/或浏览器的模块(带有Browserify )。

两个(或更多)模块,每个返回一个singelton需要在应用程序的不同部分/模块中可用。 他们也应该能够互相呼叫,所以有一个循环依赖的情况。 我知道这是可能的某种dependency injection,但我想要避免一个代码结构,我需要调用类似this.dependencies.ModuleName当从其他的一个Singeltons调用方法。 我希望能够直接调用由require-statements返回的对象的方法。

我意识到这是不可能的直接由两个CommonJS模块出口instanciated singelton对象(因为循环依赖)。 所以我希望可以使用一个共同的代码来做一些魔术。 就像是:

var Magic = require('./magic'); module.exports = Magic.createSingelton({ // ... }); 

Browserify由于循环依赖性而失败的示例:

 (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ var a = require('./class-a'), b = require('./class-b'); a.printSomething(); b.printSomething(); },{"./class-a":2,"./class-b":3}],2:[function(require,module,exports){ var b = require('./class-b'); var A = function() {}; A.prototype = { printSomething: function() { document.querySelector('body').innerHTML = document.querySelector('body').innerHTML + 'A got from B: ' + b.getSomething() + '<br />'; }, getSomething: function() { return 'FROM A'; } }; module.exports = new A(); },{"./class-b":3}],3:[function(require,module,exports){ var a = require('./class-a'); var B = function() {}; B.prototype = { printSomething: function() { document.querySelector('body').innerHTML = document.querySelector('body').innerHTML + 'B got from A: ' + a.getSomething() + '<br />'; }, getSomething: function() { return 'FROM B'; } }; module.exports = new B(); },{"./class-a":2}]},{},[1]); 

我知道RefluxJS数据商店正在以这种方式工作。 可以从商店外部或从一个商店到另一个商店调用操作。 但是,您必须创build一个操作模块和一个商店模块。 是否需要某种types的结构,或者像上面所描述的那样,每个单一的模块可以使用一个模块? 示例代码表示赞赏。

所以在你的情况下,Foo在Bar之前加载,因此Bar在加载时可以使用Foo,但是Foo在加载时不能使用Bar。

我通常做的是创build一个初始化函数(Foo.init,Bar.init),并在所有资源完成加载时调用所有初始化函数。 在你的示例代码中,这是不需要的,因为你在导出中定义的函数被允许包含对尚未加载的资源的引用:只要这些函数在加载完成之前没有被执行。