Не удается сохранить данные, полученные с помощью jQuery JSONP - PullRequest
3 голосов
/ 02 декабря 2011

Я пытаюсь получить кучу фотографий с Flickr с помощью вызова jQuery AJAX с использованием JSONP, но я не хочу использовать эти данные сразу. Вместо этого я хотел бы сохранить его для использования позже. В сложном случае я хотел бы позволить пользователям выполнять различные запросы к предварительно выбранным данным. В более простом случае я хотел бы просто загружать следующие n изображения каждый раз, когда пользователь нажимает кнопку.

Прямо сейчас я тестирую только самые базовые функции, приведенные ниже, которые адаптированы из лучшего ответа на этот вопрос: JQuery - Сохранение ответа ajax в глобальную переменную

Однако извлеченные данные JSON не сохраняются в переменной jsonData, как следует. Я поместил операторы оповещения для отладки, и странно то, что оповещение getData () срабатывает перед оповещением в функции обратного вызова. Почему это происходит?

var dataStore = ( function() {
  var jsonData;

  $.ajax({
    type: "GET",
    url: "http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?",
    dataType: "json",
    data: {
      tags: "dog",
      tagmode: "any",
      format: "json"
    },
    success: function(data) {
      jsonData = data;
      alert(jsonData);
    }
  });

  return { getData : function()
  {
      if (jsonData) return jsonData;
      else alert("no data!");
  }};
})();

var stuff = dataStore.getData();

$.each(stuff.items, function(i,item) {
  $("<img/>").attr("src", item.media.m).appendTo("#images");
  if ( i == 3 ) return false;
});

Ответы [ 2 ]

7 голосов
/ 02 декабря 2011

... и странно то, что предупреждение getData () запускается перед предупреждением в функции обратного вызова. Почему это происходит?

Поскольку вызовы ajax в целом по умолчанию асинхронны & mdash; и вызовы JSONP всегда асинхронны по своей природе (другие виды вызовов ajax могут быть сделаны синхронными, но обычно это плохая идея).

Это означает, что ваш

var stuff= dataStore.getData();

строка выполняется до завершения запроса JSONP. Именно поэтому он ничего не видит в jsonData.

Вам нужно переместить любую обработку результата вызова JSONP во что-то, вызываемое из success обратного вызова запроса.

2 голосов
/ 02 декабря 2011

Проблема в том, что stuff равен undefined, когда $.each работает, потому что stuff еще не закончил работу. Все должно быть в обратном вызове. Существует множество способов обойти это от самого уродливого и хакерского из setInterval(), который проверяет, если stuff === undefined, а если НЕТ, то делает $.each более естественным JS-способом - просто использовать обратные вызовы.

Лично я настоятельно рекомендую вам просто более эффективно использовать обратные вызовы. Вот что я бы сделал. Это должно поставить вас на правильный путь. Очевидно, что многое из этого является ложным кодом, но его можно легко изменить в соответствии с вашими потребностями.

var cachedImageData = {}; //To check if data exists for the search term

var displayImages = function(stuff){
  $.each(stuff.items, function(i,item) {
    $("<img/>").attr("src", item.media.m).appendTo("#images");
    if ( i == 3 ) return false;
  });
}

$('button').bind('click',function(){ //Triggers the ajax...
  if(cachedImageData[$('input').val()] === undefined){ //If this search doesn't exist...
    $.ajax({
      url:''
      data:{ tag: $('input').val() }, //Get the value however
      success: function(data){
        cachedImageData[$('input').val()] = data; //Save for later
        displayImages(data); //Run the display images function which is your $.each()
      }
    });
  }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...