无法存储使用jQuery JSONP获取的数据

时间:2011-12-02 08:01:32

标签: javascript jquery ajax jsonp store

我正在尝试通过使用JSONP的jQuery AJAX调用从Flickr获取一堆照片数据,但我不想立即使用这些数据。相反,我想保留它以供日后使用。在一个复杂的情况下,我想让用户对预取的数据执行不同的查询。在一个更简单的情况下,我想在每次用户点击按钮时加载下一个 n 图像。

目前,我正在测试以下最基本的功能,该功能是根据此问题的最佳答案进行调整的:JQuery - Storing ajax response into global variable

但是,检索到的JSON数据并没有像它应该那样存储在jsonData变量中。我将alert语句调试,奇怪的是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 个答案:

答案 0 :(得分:7)

  

...奇怪的是,在回调函数中的警报之前触发了getData()警报。为什么会这样?

因为默认情况下ajax调用默认是异步 - 并且JSONP调用本质上总是异步的(其他类型的ajax调用可以同步,但通常是个坏主意)。

这意味着你的

var stuff= dataStore.getData();

行在JSONP请求完成之前执行。这也是jsonData中没有看到任何内容的原因。

您需要将JSONP调用结果的任何处理移动到从请求的success回调调用的内容中。

答案 1 :(得分:2)

问题是,当stuff运行时undefined$.each,因为stuff尚未完成运行。一切都需要回调。有很多方法可以解决最丑陋和笨拙的问题,setInterval()检查stuff === undefined是否$.each如果没有,那么它会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() } }); } }); 执行更加JS原生的方式回调。

就个人而言,我强烈建议您更有效地使用回调。这就是我要做的。这应该会让你走上正轨。很明显,这很多都是虚假代码,但很容易根据您的需要进行修改。

{{1}}