require.js 同步加载

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

有没有一种方法可以做到这一点或者更好地解决这个问题?


2
我猜要使这个工作起来,require.js必须向body附加一个脚本标签,然后进入while循环以暂停执行,同时检查脚本是否正在加载。 - Jake
2个回答

19
  • 您可以尝试使用同步 RequireJS 调用 require('configs/'+get_config_name()),但它只会同步加载已经被加载过的模块,否则将抛出异常。从技术上讲,同步加载模块/JavaScript 文件是不可能的。更新:虽然有可能(参见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()包含简单逻辑并且不依赖于其他模块,则更好、更简单的方法是动态计算paths配置选项,或者如果您的配置取决于上下文-map配置选项

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

    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
    

    是的,@Henrique,你说得对。我在发布答案后才发现了这个技巧。我已经更新了答案。谢谢!顺便说一句:我认为你被投票否决是因为你将它发布为独立的答案,而不是作为评论回复。 - Maxim Kulikov
    没问题。我把它发布为答案,因为我没有“声望”来发布评论。 - Henrique
    2
    只是获取文件并将其分配给变量,就可以运行它了吗?我错过了什么? - marcus
    同步的XMLHttpRequest和eval至少在Chrome和Firefox上是可行的。 请注意,如果在本地使用它,你可能需要添加--allow-file-access-from-file参数。 - reuns
    现在,2019年,这仍然有效...您可以轻松地复制它。 我没有在规格上找到任何东西,但是当您使用content-type:application / javascript获取javascript文件时,它将运行js代码。测试: 打开Chrome开发工具并注册我的loadJS函数,然后运行loadJS('https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js')您将看到现在可用的下划线 _(您应该在其不存在之前进行测试) - Henrique

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接