我有一个应用程序,它有一个应用程序对象,它执行启动例程并存储有用的东西,如app.state
和app.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/
答案 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}在变量名的末尾。)