假设有一个函数返回包含动态依赖关系的数组。 然后在模块B中使用这些依赖关系。另一个模块A又使用模块B.
A.js
define([B], function(moduleB){
moduleB.m();
})
B.js:
define([ dep1, dep2 ], function( dep1, dep2 ) {
var dyndeps = dep2.getDynDeps();
var moduleB = {}
require(dyndeps, function() {
moduleB.m = function() { ... };
})
return moduleB;
});
这种方法的问题是,内部需求是异步执行的,因此方法m不能及时获得。
答案 0 :(得分:9)
由于B.m
由动态依赖项提供,B
应该提供一个等待它可用的接口。有许多plugins允许这样做,例如 rq (使用Q承诺), promise (使用jquery,Q,RSVP或ES6承诺), promiseme (自包含?)。
使用其中一个,B
不会返回moduleB
,而是一个承诺。嵌套的require
调用将使用完整的moduleB
解析承诺。 A
需要<PLUGIN>!B
。例如。使用promise
和jquery
:
// A.js
define(["promise!B"], function(moduleB){
// B is complete now
moduleB.m();
})
// B.js
define([ "dep1", "dep2", "jquery" ], function( dep1, dep2, $ ) {
var dyndeps = dep2.getDynDeps();
var moduleB = {};
var loaded = new $.Deferred();
require(dyndeps, function() {
moduleB.m = function() { ... };
loaded.resolve(moduleB);
})
return loaded.promise();
});
此方法唯一存在的问题是客户端代码(A.js
)需要知道以特殊方式依赖B
。更好的解决方案是让B
隐藏其动态特性,如:
// A.js
define(["B"], function(moduleB){
moduleB.m();
})
// B.js
define([ "promise!dynamicB" ], function( moduleB ) {
return moduleB;
});
// still inside B.js define a "private" named module:
define("dynamicB", ["dep1", "dep2", "jquery"], function() {
var dyndeps = dep2.getDynDeps();
var loaded = new $.Deferred();
var moduleB = {};
require(dyndeps, function() {
moduleB.m = function() { ... };
loaded.resolve(moduleB);
})
return loaded.promise();
});
现在B
可以像任何其他模块一样使用。