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
(это имя рассматриваемого параметра), но в некоторых отчетах об ошибках упоминается об этом, и я не видел там ни одного комментария о том, что он предназначен для частной функциональности.