Загрузка jQuery getScript и исполнение
В документах getScript говорится об обратном вызове успеха, который:
"Обратный вызов запускается, как только script загружен, но не обязательно выполняется."
Но в моем тестировании это не похоже на правду. Для главной страницы с:
var startTime = new Date();
$.getScript("test.js")
.done(function( script, textStatus ) {
console.log( textStatus );
console.log( "Done callback executing now.")
})
.fail(function( jqxhr, settings, exception ) {
console.log("error." );
});
загрузите следующий "test.js" script, который связывает пользовательский интерфейс в течение 5 секунд:
console.log("ajaxed script starting to execute.");
var newTime = new Date();
while (newTime - startTime < 5000) {
newTime = new Date();
}
console.log("elapsed time", newTime - startTime);
console.log("ajaxed script finished executing.");
приводит к тому же прогнозируемому выпуску консоли как в FF, так и в Chrome:
ajaxed script starting to execute.
elapsed time 5000
ajaxed script finished executing.
success
Done callback executing now.
Другими словами, обратный вызов успеха никогда не срабатывает, пока загруженный и выполняемый загруженный script не загружается. Кажется, это связано с тем, что в источнике jQuery функция globalEval немедленно вызывает script:
converters: {
"text script": function( text ) {
jQuery.globalEval( text );
return text;
}
}
Значит, документы неправильные? Если они верны, то в каких конкретных случаях будет выполняться обратный вызов успеха до выполнения script?
Ответы
Ответ 1
Из того, что я могу сказать, глядя на источник, я согласен с вашим заключением, что обещание должно всегда разрешать после, выполненный script.
Однако моя память говорит мне, что была какая-то странность в том, что вы вводили теги <script>
в одном из многих браузеров. Поддержка jQuery 1.x (s|ed)
. Браузер проблем запускал загруженные обратные вызовы до того, как в какой-то момент был выполнен script, или мы не добавили бы примечания об этом в документы.
Я уверен, что реализация $.getScript
с тех пор изменилась, а проблемная строка в документах больше не актуальна, так как нам нужно задать вопрос перед основной командой jQuery. Вы действительно должны открыть проблему на github - не стесняйтесь cc @gnarf.
Ответ 2
Это цитата из ответа на проблема GitHub, поданная оригинальным плакатом:
$.getScript("https://platform.twitter.com/widgets.js").done(..)
с некоторыми твиттер файлами будет запускать готовый код, не дожидаясь выполнения выполнения.
Таким образом, документация кажется правильной, хотя, возможно, не такой описательной, как хотелось бы.
Ответ 3
Я столкнулся с этой проблемой в версии 1.1.1 jQuery. Перед версией 2.1.0 функция $.globalEval()
, использовавшая косвенный вызов печально известного eval()
, выполняла код в глобальной среде.
Так что это определенно было проблемой раньше.
В версии 2.1.0 они переключились на вставку script из-за определенных недостатков в косвенном вызове eval. Вы можете найти больше информации, если хотите.
http://perfectionkills.com/global-eval-what-are-the-options/
В более новой версии с вставкой script эта строка делает магию
context.head.appendChild( script ).parentNode.removeChild( script );
Если не существует какого-то странного базового механизма браузера, кажется, что script должен выполняться немедленно, перед удалением из дерева DOM.