#javascript #function #execute
#javascript #функция #выполнить
Вопрос:
Я создаю фреймворк, который позволяет мне начинать с обычного статического веб-сайта, а затем, если у пользователя включен Javascript, преобразовывает его в одностраничный сайт, который извлекает разделы со статических страниц по мере навигации пользователя по сайту.
Я все еще работаю над идеями, но мне трудно понять, как выполнять функции Javascript в определенном порядке, мой код (отредактированный) выглядит следующим образом:
ОТРЕДАКТИРУЙТЕ мой код более подробно:
Когда функция loadSiteMap() завершает работу, переменная siteMap выглядит следующим образом:
{
"pageData" : [
{
"loadInTo" : "#aboutUs",
"url" : "aboutUs.html",
"urlSection" : ".sectionInner"
},
{
"loadInTo" : "#whatWeDo",
"url" : "whatWeDo.html",
"urlSection" : ".sectionInner"
},
{
"loadInTo" : "#ourValues",
"url" : "ourValues.html",
"urlSection" : ".sectionInner"
},
{
"loadInTo" : "#ourExpertise",
"url" : "ourExpertise.html",
"urlSection" : ".sectionInner"
}
]
}
Остальная часть моего кода:
function loadSiteMap() {
$('#body').empty();
$.ajaxSetup({cache : false});
$.ajax({
url: 'js/siteMap.js',
async: false,
dataType: 'json'
})
.done(function(data){
siteMap = data;
})
.fail(function(jqXHR, status){
alert('Its all gone to shit');
});
}
loadSiteMap();//So this is the first to be executed
$(function(){
function loadDataFromSiteMap() {
var toAppend = '';
var markerID = 'mark-end-of-append' (new Date).getTime();
var loadGraphic = '<img src="images/loadGraphic.gif" alt="loading..." class="loadGraphic" />'
for(var i=0; i<siteMap.pageData.length; i ) {
var loader = siteMap.pageData[i];
toAppend = '<div id="' loader.loadInTo.substr(1) '" class="sectionOuter">' loadGraphic '</div>';
}
toAppend = '<div id="' markerID '"></div>';
$('#body').append(toAppend);
var poller = window.setInterval(function(){
var detected = document.getElementById(markerID);
if(detected){
window.clearInterval(poller);
$(detected).remove();
for(var i=0; i<siteMap.pageData.length; i ){
var loader = siteMap.pageData[i];
var dfd = $.ajax({
url: loader.url,
async: false
});
dfd.done(function(data, status, jqXHR){
var sections = $(data).find(loader.urlSection);
$(loader.loadInTo).html(sections).filter(loader.urlSection);
});
dfd.fail(function(jqXHR, status){
alert('Its all gone to shit');
});
}
}
}, 100);
}
function buildCarousel() {
$('.sectionInner').each(function(i) {
if($(this).has('.carousel').length) {
$(this).append('<a href="#" class="prev">Prev</a><a href="#" class="next">Next</a>');
$('.prev,.next').fadeIn('slow');
}
});
};
loadDataFromSiteMap();//This runs second then I want to execute...
buildCarousel();//Then when this is complete execute...
anotherFunction();//and so on...
Надеюсь, из этого вы сможете понять, чего я пытаюсь достичь с точки зрения выполнения функций по порядку. Я хотел бы в конечном итоге превратить эту концепцию в плагин jQuery, чтобы я мог поделиться ею. Если это имеет какое-либо отношение к тому, чего я пытаюсь достичь сейчас, я приветствую мысли.
Заранее большое спасибо.
Ответ №1:
Я думаю, что AJAX — это один из немногих случаев, когда вам придется беспокоиться о том, что функции не выполняются в определенном порядке в JavaScript.
Хитрость асинхронных вызовов функций, таких как AJAX, заключается в использовании обратных вызовов. Поместите все, что находится в разделе «Doc ready», в другую вызываемую функцию (или просто анонимную функцию в коде AJAX complete), затем вызывайте эту функцию только после завершения вашего AJAX-вызова. Причина в том, что остальная часть вашей программы будет выполняться во время обработки вызова AJAX, поэтому обратные вызовы гарантируют, что вызов AJAX будет выполнен, прежде чем продолжить то, что вы хотите выполнить дальше.
Если какая-либо из этих других функций является асинхронной, вам придется аналогичным образом выполнить обратный вызов по завершении, который продолжит выполнение остальных функций.
Однако в нынешнем виде я не вижу причин, по которым каждая функция, кроме AJAX, не должна вызываться по порядку. По крайней мере, не зная, как работают эти функции.
Редактировать: пример кода обратного вызова:
$.ajax({
url: 'ajax/test.html',
success: function(data) {
//Set sitemap
(function() {
//Make the calls to your list of functions
})(); //<- Execute function right away
}
});
Кроме того, согласно here, async: false не будет работать с «междоменными запросами и запросами типа данных: «jsonp», поэтому, если вы вызываете другой домен или используете jsonp, это может быть проблемой.
Комментарии:
1. Спасибо за ответ, Боб. Я установил для всех своих вызовов ajax значение async: false, так что разве это не должно означать, что они выполняются по очереди? Также не могли бы вы показать мне пример кода для вашего предложения? или ссылку, где я могу узнать больше. Я не самый лучший с JS.
2. @mtwallet, да, они должны. Какие функции выполняются / не выполняются в порядке? Я думаю, что мне нужно больше контекста здесь
3. большое спасибо! Я только что закончил обновлять свой пост, чтобы показать полный код. Я использую новые методы. сделано amp; .fail но я попробую ваше предложение.
4. это сработало! Могу ли я использовать этот метод в любой функции таким же образом? Большое спасибо за вашу помощь, я ценю это.
5. @mtwallet Я рад, что это сработало 🙂 Что касается вашего вопроса: вы можете использовать метод обратного вызова в любом вызове .ajax таким же образом, да, если вы это имеете в виду. Трюк с созданием функции и ее немедленным вызовом также работает в любом месте