RequireJS模块相互引用

时间:2014-01-24 09:29:12

标签: requirejs

我正在使用requirejs加载一个Web应用程序构建的几个模块,但我很难理解某些东西。我的主要模块需要它依赖,但其他定义的模块都以某种方式相互引用。所以我们可以说'project / func'模块可以在'project / save'模块中调用一个save函数。现在我的大部分代码都导致了未定义的错误。

从在线阅读中我可能会遇到一个称为循环引用的东西?我不太确定。我想我需要知道我做错了什么以及我应该怎么做。我试过在下面给一个例子,主文件在其中一个模块中调用bootstrap方法但该模块在某个时候调用另一个模块。这只是一个小例子。真正的应用程序有许多模块,如果有意义的话,它们都需要在彼此内部运行函数。

//main require
require(['jquery', 'jqueryui', 'project/save', 'project/funcs', 'project/spec'], function($, ui, proSave, proFunc, proSpec){
    proFunc.bootstrap();     
});

//project/save
define(function(){
    var save = function(){
        //do some save stuff here
    }
    return {
        save: save
    }
});

//project/funcs
define(['project/save'], function(proSave){
    var funcs = {
        bootstrap: function(){
            //do some stuff 
            funcs.func1();
        },
        func1: function(){
        //do some stuff and save
        proSave.save();
    }
    }
    return {
        funcs: funcs
    }
});

1 个答案:

答案 0 :(得分:5)

RequireJS对循环依赖关系有documentation,解释了如何处理它们:

  

如果定义循环依赖(需要b和b需要a),那么在这种情况下调用b的模块函数时,它将获得a的未定义值。 b可以在使用require()方法定义模块后稍后获取(确保将require指定为依赖项,以便使用正确的上下文查找a):

//Inside b.js:
  define(["require", "a"],
    function(require, a) {
        //"a" in this case will be null if a also asked for b,
        //a circular dependency.
        return function(title) {
            return require("a").doSomething();
        }
    }
  );

因此,您必须编写代码,以便能够处理循环依赖项中的模块定义最初未定义的事实。有关如何完成此操作的详细信息取决于应用程序的特定结构。

来自RequireJS文档的这些智慧之词值得关注:

  

循环依赖很少见,通常表示您可能想重新考虑设计。

[强调补充。]通常情况下,如果模块A依赖于B而B取决于A,则有一部分功能要从A或B中提取并移入模块C,这将允许A依赖于C而不是B,而B依赖于C而不是A,并打破循环依赖。为了每个人都使用这样的代码,这是最好的选择。然后,在极少数情况下无法去除圆形度,我上面引用的文档告诉您如何处理它。