синхронная загрузка require.js

Я хотел бы определить модуль, который вычисляет новую зависимость, извлекает ее и затем возвращает результат. Вот так:

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

Есть ли способ сделать это или лучший способ решить эту проблему?


person Jake    schedule 05.11.2012    source источник
comment
Я предполагаю, что для того, чтобы это работало, require.js должен был бы добавить тег скрипта к телу, а затем перейти в цикл while, чтобы приостановить выполнение, пока он проверяет загрузку скрипта.   -  person Jake    schedule 05.11.2012


Ответы (2)


  • Вы можете попробовать использовать синхронный вызов RequireJS require('configs/'+get_config_name()), но он загрузит модуль синхронно, только если он < strong>уже загружен, иначе будет выдано исключение. Синхронная загрузка модуля/файла JavaScript технически невозможна. UPD: Возможно (см. ответ Энрике), но крайне не рекомендуется. Он блокирует выполнение 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);
    });
    
person Maxim Kulikov    schedule 07.01.2013

Синхронная загрузка 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
person Henrique    schedule 18.01.2015
comment
Да @Энрике, ты прав. Я обнаружил эту технику после того, как опубликовал ответ. Я обновил ответ. Спасибо! Кстати: я думаю, что за вас проголосовали, потому что вы опубликовали его не как комментарий к ответу, а как отдельный ответ. - person Maxim Kulikov; 01.02.2015
comment
Без проблем. Я опубликовал как ответ, потому что у меня нет репутации, чтобы публиковать комментарии. - person Henrique; 02.02.2015
comment
Просто извлечение файла и присвоение его переменной запустит его? Что мне не хватает? - person marcus; 04.11.2015
comment
синхронный XMLHttpRequest и eval возможны по крайней мере в chrome и firefox. обратите внимание, что при локальном использовании вам, вероятно, понадобится --allow-file-access-from-file - person reuns; 30.12.2015
comment
Теперь, в 2019 году, это все еще работает... вы можете легко воспроизвести это. Я ничего не нашел в спецификациях, но когда вы получаете файл javascript с помощью content-type: application/javascript, он запускает код js. Чтобы проверить: откройте инструменты chrome dev, зарегистрируйте мою функцию loadJS и запустите loadJS('https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js'). Вы увидите, что подчеркивание _ теперь будет доступно (вы должны проверить его отсутствие раньше) - person Henrique; 14.05.2019