【问题标题】:require.js synchronous loadingrequire.js 同步加载
【发布时间】:2012-10-24 21:12:37
【问题描述】:

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

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

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

【问题讨论】:

  • 我想这需要 require.js 必须在正文中附加一个脚本标记,然后跳转到一个 while 循环以暂停执行,同时检查要加载的脚本。

标签: import module requirejs synchronous


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

  • 从您的用例看来,您不需要同步RequireJS,您需要异步返回结果AMD 模式允许定义依赖并异步加载它们,但模块的工厂函数必须同步返回结果。解决方案可能是使用loader plugin(详情herehere):

    // 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 configuration option,或者如果您的配置依赖于上下文 - map configuration option

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

【讨论】:

    【解决方案2】:

    同步加载 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,你是对的。我在发布答案后发现了这种技术。我更新了答案。谢谢!顺便说一句:我认为您被否决了,因为您发布它不是作为对答案的评论,而是作为单独的答案。
    • 没问题。我作为答案发表是因为我没有“声誉”来发布 cmets。
    • 只是获取文件并将其分配给变量会运行它吗?我错过了什么?
    • 同步 XMLHttpRequest 和 eval 至少在 chrome 和 firefox 上是可能的。请注意,如果在本地使用它,您可能需要 --allow-file-access-from-file
    • 现在,2019 年,这仍然有效……您可以轻松复制它。我没有在规范上找到任何东西,但是当您使用 content-type: application/javascript 获取 javascript 文件时,它将运行 js 代码。测试:打开 chrome 开发工具并注册我的 loadJS 函数并运行 loadJS('https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js') 你会看到下划线 _ 现在可用(你应该测试它之前不存在)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-20
    • 2019-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-21
    • 1970-01-01
    相关资源
    最近更新 更多