#javascript #jquery #ajax #get
#javascript #jquery #ajax #получить
Вопрос:
У меня есть 2 вызова Get API JAVASCRIPT, которые я выполняю с помощью JQUERY. Я хочу добавить HTML, который я создаю во время второго вызова DOM.
Первый вызов захватывает некоторые данные. Я перебираю длину этих данных, делая второй вызов для каждого индекса.
Во время второго вызова я создаю HTMLContent.
Как только все вызовы выполнены, я добавляю HTMLContent в DOM.
Я изо всех сил пытаюсь вернуть HTMContent обратно в пределах первого вызова, так как я хочу добавить DOM только тогда, когда он будет полностью создан. И вне for
созданного мной цикла.
Я знаю, что мог бы добавить done из 2-го вызова, но мне бы очень хотелось знать, как его вернуть.
Я подумал, возможно, мне нужно создать обещание, но не уверен, что это поможет, так как область по-прежнему будет содержаться во второй .done
функции запроса get.
Это то, что у меня есть до сих пор.
var gallery = (function($){
var init,
firstGetCall,
secondGetCall,
HTMLContent = '';
init = function(){
// Make first call
firstGETCall();
};
// Declare firstGETCall func
firstGETCall = function(){
$.ajax({
url: 'http://example.com/data.json',
type: 'GET',
data: {
numberOfItems: 10
}
})
.done(function(data) {
// Cycle through each data element
for (var i = 0; i < data.length; i ) {
// Make second call
secondGetCall(data[i]);
};
})
.fail(function(error) {
console.log(error);
});
// I want to append the DOM here with the conplete HTMLContent - built up of 10 x <div><img... elements
// However I'm stuck as to how to return the complete HTMLContent
};
// Declare secondGetCall func
secondGetCall = function(singleData) {
$.ajax({
url: 'http://example.com/data-2.json',
type: 'GET',
data: {
type: singleData
}
})
.done(function(data) {
// Build HTMLContent
HTMLContent = '<div><img src="' data.image ' title="' data.subTitle ' alt="Photo"></div>';
// I do not want to append the DOM here
// return HTMLContent doesn't work
})
.fail(function(error) {
console.log(error);
});
};
return {
init: init
};
})(jQuery);
gallery.init(jQuery);
Ответ №1:
Сначала самый важный момент:
Я хочу добавить сюда DOM…
В любом случае, вы ничего не можете сделать в том месте, где вы разместили приведенный выше комментарий!
Поскольку Ajax работает асинхронно (если вы не укажете обратное, но это настоятельно не рекомендуется), любой оператор в указанном вами месте будет выполнен через несколько микросекунд после $.ajax
запуска, так что пройдет много времени, прежде чем будет собран весь ваш HTML.
Теперь это тоже кажется странным:
Я изо всех сил пытаюсь вернуть HTMContent обратно в пределах первого вызова
Во-первых, потому что, опять же из-за асинхронного режима, вы не можете ожидать возврата чего-либо из .done()
вызова Ajax.
Но также и потому, что я не понимаю, почему вы хотите «вернуть» данные, которые уже доступны на более высоком уровне. На самом деле вам нужно только получать уведомления, когда они будут доступны.
С другой стороны, я полностью согласен, что лучше добавлять HTML в DOM только один раз, чтобы сократить затраты времени.
Затем, чтобы это сработало, моя первая мысль такова: почему бы просто не иметь уникальную серверную функцию, возвращающую весь набор необходимых данных, а не два разных?
Однако, в случае, если по какой-то причине это действительно невозможно, вы можете фактически заставить вызовы Ajax работать синхронно (но, опять же, вам следует избегать этого).
В этом случае вам необходимо :
- В вашей
secondGetCall()
функции слегка измените оператор.done()
body, чтобы добавлять новые данныеHTMLContent
, а не просто устанавливать их :HTMLContent = '<div>...</div>'
; . - В каждом из двух вызовов Ajax добавьте
async: false
к объекту Ajax. - Напишите инструкцию для добавления HTMLContent в DOM в том месте, где вы написали комментарий об этом.
Комментарии:
1. Спасибо @cFreed — похоже, я хочу сохранить его асинхронным. Как мне изменить то, что мне нужно для этого? Опять же, изо всех сил пытаюсь понять, где и как я могу поместить уведомление, чтобы сообщить, когда все будет завершено и будет создан HTMLContent.
2. и в вашем ответе в пункте 1. Если я не ошибаюсь, я добавляю (объединяю) новые данные с помощью
=
присваивания3. @fidev Сначала отвечаю на ваш последний комментарий: да, я предлагаю последовательно заполнять
HTMLContent
, добавляя каждую новую часть, затем (пункт 3) использовать фактический весь HTML-текст для добавления в DOM. Что вас здесь озадачивает?4. @fidev Относительно вашего предыдущего комментария: труднее получить хороший ответ. Если вы хотите сохранить его асинхронным, единственный другой способ, который я могу придумать, это что-то вроде: 1) добавьте
.complete()
обработчик вsecondGetCall()
, где вы увеличиваете счетчик (ранее определенный в верхней части функции); 2) добавьте.complete()
обработчик вfirstGETCall()
, где вы добавляете HTML к DOM, когда счетчик ==желаемое количество элементов . Но вы должны понимать, что это просто еще один способ синхронной работы! Поэтому я еще раз предлагаю вам рассмотреть возможность работы раз и навсегда на уровне сервера.