Я знаю, здесь уже много вопросов об AJAX и синхронности, но я почему-то не нашел правильного ответа на мое дело. Пожалуйста, будьте осторожны, я ноб, так что это может быть дубликат. Тем не менее, даже намек на это может помочь мне и другим найти правильный ответ.Несколько вложенных вызовов AJAX в jQuery: как это сделать правильно, не возвращаясь к синхронному?
Функция
$.fn.facebookEvents = function(options){
var fbEvents = 'https://graph.facebook.com/'+options.id+'/events/?access_token='+options.access_token+'&since=now&limit=500';
var events = [];
$.when($.getJSON(fbEvents)).then(function(json){
$.each(json.data, function(){
$.getJSON('https://graph.facebook.com/'+this.id+'/?access_token='+options.access_token, function(jsonData){
events.push(jsonData);
console.log(events); // here array "events" is filled successively
});
console.log(events); // here array "events" remains empty
});
}).done(function(){
$("#fb_data_live").html(
$("#fb_events").render(events)
);
});
};
Что происходит в этой функции является AJAX вызовов (через jQuerys getJSON стенографии) для списка событий на странице Facebook. Это вернет список объектов JSON, представляющих каждую дату. Пример одного объекта в качестве ответа:
{
"end_time": "2017-03-16T23:00:00+0100",
"location": "Yuca K\u00f6ln",
"name": "K\u00f6rner // G\u00e4nsehaut Tour 2017 // K\u00f6ln",
"start_time": "2017-03-16T20:00:00+0100",
"timezone": "Europe/Berlin",
"id": "985939951529300"
},
К сожалению, эти данные не имеют необходимой информации. Они скрыты (вложены) и могут быть найдены после создания второго getJSON (строка 8 в функции) с использованием индивидуального «id» каждого объекта. В настоящее время Facebook отвечает:
{
"description": "http://www.eventim.de/koerner\nTickets ab sofort exklusiv auf eventim.de und ab MI 07.09. \u00fcberall wo es Tickets gibt sowie auf contrapromotion.com.",
"end_time": "2017-03-16T23:00:00+0100",
"is_date_only": false,
"location": "Yuca K\u00f6ln",
"name": "K\u00f6rner // G\u00e4nsehaut Tour 2017 // K\u00f6ln",
"owner": {
"name": "K\u00f6rner",
"category": "Musician/Band",
"id": "366592010215263"
},
"privacy": "OPEN",
"start_time": "2017-03-16T20:00:00+0100",
"timezone": "Europe/Berlin",
"updated_time": "2016-09-28T10:31:47+0000",
"venue": {
"name": "Yuca K\u00f6ln"
},
"id": "985939951529300"
}
Et voila, подробности, которые я искал. После выполнения этого второго (вложенного) вызова AJAX я выталкиваю данные JSON в массиве «события» (строка 12).
Проблема
Это должно заполнить массив с каждой итерации .each. Однако взгляните на два «console.logs». Первый возвращает заполненный массив, второй возвращает пустой массив ... Если вызовы AJAX выполняются синхронно (что не так, как должно быть), например. добавив $.ajaxSetup({async: false});
до функции, он работает отлично. Массив заполняется и может быть отображен (строка 18).
Вопрос
Как это поведение можно объяснить и как эта функция может быть сделано правильно? Я знаю, должен быть способ использовать отложенные и обещания? Я думал, что сделал, используя .если тогда ... я ... я ошибся.
С наилучшими пожеланиями, Джулиуса