Require.js (almond.js) Время выключено

Я пытаюсь использовать Almond.js и оптимизатор Require.js, чтобы создать отдельный файл, который можно использовать без Require.js. Мне удалось успешно скомпилировать файл, и весь код выполняется, но есть одна проблема: код выполняется в неправильном порядке.

Допустим, мой основной файл (тот, который находится в include= Опция, переданная оптимизатору) имеет следующее:

console.log('outside');
require(['someFile'], function(someModule) {
    console.log('inside');
    window.foo = someModule.rightValue;
});

и затем в моем HTML у меня есть:

<script src="myCompiledFile.js"></script>
<script>
    console.log('out in the HTML');
</script>

Поскольку я использую almond.js и скомпилированный файл (и, следовательно, загрузка файла не происходит), я ожидаю получить вывод:

outside
inside
out in the HTML

Тем не менее, оказывается, что все еще происходит некоторая асинхронность, потому что на самом деле я вижу:

outside
out in the HTML
inside

и если я попытаюсь проверить window.foo из HTML его там нет.

Итак, мой вопрос, как я могу сделать код более похожим на обычный / синхронный JS-файл, который сначала выполняет весь свой код, а затем передает следующее script блок? Я не могу точно сказать своим пользователям "обернуть весь ваш код в window.setTimeout".

1 ответ

Решение

По умолчанию Almond воспроизводит семантику синхронизации RequireJS' require вызов. поскольку require асинхронный в RequireJS, он также асинхронный в Almond. Это можно легко увидеть в источнике: Миндаль использует setTimeout планировать выполнение модуля, даже если он может выполнить его сразу. Это имеет смысл, потому что в общем случае разработчики не ожидают, что код, созданный ими для асинхронной работы, внезапно станет синхронным только потому, что они используют Almond. Это не имеет значения в каждом проекте, но в проекте, где пользовательский интерфейс (например) должен обновляться в определенном порядке, изменение семантики синхронизации может нарушить код.

Два варианта:

  • Как комментарий прямо перед setTimeout состояния, используя require('id') работает во всем мире с миндалем. Это потому, что как только ваш пакет загружен, все гарантированно будет загружено (поскольку Almond не загружается динамически).

  • Также есть способ позвонить require с дополнительными аргументами. Если четвертый аргумент равен true, вызов будет синхронным:

    require(['someFile'], function(someModule) {
        console.log('inside');
        window.foo = someModule.rightValue;
    }, undefined, true);
    

В этом можно убедиться, прочитав код Almond. Там нет документации, которую я мог бы найти на forceSync (это имя рассматриваемого параметра), но в некоторых отчетах об ошибках упоминается об этом, и я не видел там ни одного комментария о том, что он предназначен для частной функциональности.

Другие вопросы по тегам