RequireJS会在app上访问app对象

时间:2014-05-17 22:20:03

标签: requirejs circular-dependency shared-objects

我有一个应用程序,它有一个应用程序对象,它执行启动例程并存储有用的东西,如app.stateapp.user。但是,我尝试访问此应用实例,而不是在我的大型代码库的整个应用实例中传递this

奇怪的是,我在其他项目中工作的方式与something.js中的应用程序相同,并且有效,但我无法理解原因。

的index.html

<!DOCTYPE html>
<html>
<head>
    <title>Cannot require app in another file</title>
</head>
<body>
    <script data-main="config" src="require.js"></script>
</body>
</html>

config.js

requirejs.config({
    deps: ['app']
});

app.js

define([
    'something'
], function(Something) {
    'use strict';

    var App = function() {
        this.name = 'My app';
    };

    return new App();
});

something.js

define([
    'require',
    'app'
], function (require, app) {
    'use strict';

    var SomeModule = function() {
        app = require('app'); // EXCEPTION
        console.log('App:', app);
    };

    return new SomeModule();
});

加载此requirejs时因为SomeModule中的要求而抛出异常:

未捕获错误:模块名称&#34; app&#34;尚未加载上下文:_

以上演示(请参阅控制台查看错误):http://dominictobias.com/circulardep/

1 个答案:

答案 0 :(得分:1)

我不清楚为什么你需要循环依赖。正如Require {documentation中所述:

  

循环依赖很少见,通常是您可能想要重新考虑设计的标志。

这就是说,如果你确实需要循环依赖,那么代码的问题是过早地调用require('app')。只有在模块something返回其值后 之后才能调用它。现在,它被称为之前返回的值。如果你看一下文档中给出的代码:

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();
        }
    }
);

你看到模块返回一个函数,然后由需要该模块的代码调用,该函数在该模块返回其值后发生。

那你怎么解决这个问题呢?你可以做的是让你返回的类调用一个函数,在需要时获取模块app。所以:

define([
    'require',
    'app'
], function (require) {
    'use strict';

    var app_;
    function fetch_app() {
        if (app_ === undefined)
            app_ = require("app");
        return app_;
    }

    var SomeModule = function() {
        // ...
    };

    SomeModule.prototype.doSomethingWithApp = function () {
        var app = get_app();
        app.whatever();
    };

    return new SomeModule();
});

我已从参数列表中删除了app,并将app模块的值存储在app_中,因为这样做可以及早发现对{的遗失调用在get_app()的任何方法中{1}}。如果SomeModule成为模块工厂函数的参数,那么只有在没有其他方法调用{{1}的情况下才会检测到在方法中使用app而不首先调用app首先被调用。 (当然,我可以输入get_app()并遇到与我想要预防的问题相同的问题。这是各自可能性的问题:我很可能忘记致电get_app() 它是必需的,因为我通常不会编写带有循环依赖的代码。但是,我不太可能为app_键入get_app(),因为我通常不会{{1}在变量名的末尾。)