RequireJS跨应用程序访问应用程序对象时出现问题

RequireJS跨应用程序访问应用程序对象时出现问题,requirejs,circular-dependency,shared-objects,Requirejs,Circular Dependency,Shared Objects,我有一个应用程序,它有一个app对象,它执行启动例程并存储有用的东西,如app.state和app.user。但是,我尝试访问此应用程序实例,而不将此从应用程序实例传递到我的大型代码库中 奇怪的是,我用与something.js中相同的方式处理其他包含应用程序的项目,但我不明白为什么 index.html <!DOCTYPE html> <html> <head> <title>Cannot require app in another f

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

奇怪的是,我用与
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>
app.js

requirejs.config({
    deps: ['app']
});
define([
    'something'
], function(Something) {
    'use strict';

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

    return new App();
});
define([
    'require',
    'app'
], function (require, app) {
    'use strict';

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

    return new SomeModule();
});
something.js

requirejs.config({
    deps: ['app']
});
define([
    'something'
], function(Something) {
    'use strict';

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

    return new App();
});
define([
    'require',
    'app'
], function (require, app) {
    'use strict';

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

    return new SomeModule();
});
加载此requirejs时,由于
SomeModule
中的require,会引发异常:

未捕获错误:尚未加载上下文的模块名“app”:


上面的演示(错误请参见控制台):

我不清楚为什么需要循环依赖项。如要求中所述:

循环依赖关系很少见,这通常是一个迹象,表明您可能需要重新考虑设计

也就是说,如果您确实需要循环依赖项,那么代码的问题是
require('app')
调用得太早。只有在模块
某物
返回其值后才能调用它。现在,在返回值之前,它被称为。如果您查看文档中作为示例给出的代码:

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
中,因为这样做可以在
SomeModule
的任何方法中提前检测到对
get\u app()
的丢失调用。如果将
app
设置为模块工厂函数的参数,则仅当没有首先调用调用
get\u app()
的其他方法时,才会检测到在方法内部使用
app
,而不先调用
get\u app()
。(当然,我可能会键入
app
,然后面临与我要预防的问题相同的问题。这是一个各自的可能性问题:我很可能会忘记调用
get\u app()
在任何地方都需要它,因为我通常不会编写循环依赖的代码。但是,我不太可能为
app
键入
app
,因为我通常不会在变量名的末尾添加

谢谢您的详细回复。我在想你/医生对circular dep的看法,我想我只是从另一个应用程序中吸取了这个坏习惯,但没有充分考虑它-你是对的,我不需要为了访问一些连接的对象而做这个循环,我可以在需要的地方使用。是的,摆脱循环依赖将使事情变得更简单。总结一下,读者们:在初始化例程期间,基本上不能要求应用程序内的
新的
依赖项