不能存储使用jQuery JSONP获取的数据

Can't store data fetched with jQuery JSONP

本文关键字:获取 数据 JSONP jQuery 存储 不能      更新时间:2023-09-26

我试图通过jQuery AJAX调用使用JSONP从Flickr获取一堆照片数据,但我不想马上使用这些数据。相反,我想把它保存起来以备以后使用。在复杂的情况下,我希望让用户对预取的数据执行不同的查询。在一个更简单的情况下,我只想在用户每次单击按钮时加载下一个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;
});

…奇怪的是,getData()警报在回调函数中的警报之前触发。为什么会发生这种情况?

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

这意味着你的

var stuff= dataStore.getData();

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

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

问题是$.each运行时stuffundefined,因为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()
      }
    });
  }
});