23

我想定义一个模块来计算新的依赖关系,获取它然后返回结果。像这样:

define(['defaults', 'get_config_name'], function(defaults, get_config_name) {
    var name = get_config_name();
    var config;
    require.synchronous([configs / '+name'], function(a) {
        config = defaults.extend(a);
    });
    return config;
});

有没有办法做到这一点或更好的方法来解决这个问题?

4

2 回答 2

19
  • 您可以尝试使用同步 RequireJS 调用 require('configs/'+get_config_name()),但只有在模块已经加载时才会同步加载,否则会抛出异常。同步加载模块/JavaScript 文件在技术上是不可能的。 UPD: 这是可能的(见 Henrique 的回答),但非常不推荐。它会阻止导致整个页面冻结的 JavaScript 执行。所以,RequireJS 不支持它。

  • 从您的用例看来,您不需要同步 RequireJS,您需要异步返回结果AMD模式允许定义依赖关系并异步加载它们,但模块的工厂函数必须同步返回结果。解决方案可能是使用加载器插件此处此处的详细信息):

    // config_loader.js
    define(['defaults', 'get_config_name'], function(defaults, get_config_name) {
        return {
            load: function (resourceId, require, load) {
                var config_name = 'configs/' + get_config_name();
                require([config_name], function(config) {
                    load(defaults.extend(config));
                })
            }
        }
    });
    
    // application.js
    define(['config_loader!'], function(config) {
        // code using config
    });
    
  • 如果get_config_name()包含简单的逻辑并且不依赖于其他模块,则更好更简单的是在飞行路径配置选项上进行计算,或者如果您的配置依赖于上下文映射配置选项

    function get_config_name() {
        // do something
    }
    require.config({
        paths: {
            'config': 'configs/' + get_config_name()
        }
    });
    require(['application', 'defaults', 'config'], function(application, defaults, config) {
        config = defaults.extend(config);
        application.start(config);
    });
    
于 2013-01-07T17:51:51.017 回答
15

同步加载 JavaScript 在技术上并非不可能。

function loadJS(file){  
   var js = $.ajax({ type: "GET", url: file, async: false }).responseText; //No need to append  
}

console.log('Test is loading...');
loadJS('test.js');
console.log('Test was loaded:', window.loadedModule); //loadedModule come from test.js
于 2015-01-18T14:42:55.770 回答