简体   繁体   English

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

[英]Can't store data fetched with jQuery JSONP

I'm trying to fetch a bunch of photo data from Flickr via a jQuery AJAX call using JSONP, but I don't want to use the data right away. 我试图通过使用JSONP的jQuery AJAX调用从Flickr获取一堆照片数据,但我不想立即使用这些数据。 Instead, I'd like to preserve it for use later. 相反,我想保留它以供日后使用。 In a complicated case, I'd like to let users perform different queries on the prefetched data. 在一个复杂的情况下,我想让用户对预取的数据执行不同的查询。 In a simpler case, I'd like to just load the next n images each time the user clicks a button. 在更简单的情况下,我想在每次用户单击按钮时加载下n个图像。

Right now, I'm testing just the most basic functionality below, which is adapted from the best answer to this question: JQuery - Storing ajax response into global variable 现在,我正在测试下面最基本的功能,它是根据这个问题的最佳答案改编的: JQuery - 将ajax响应存储到全局变量中

However, the retrieved JSON data is not getting stored in the jsonData variable as it should. 但是,检索到的JSON数据不会存储在jsonData变量中。 I put the alert statements to debug, and the strange thing is that the getData() alert is triggered before the alert in the callback function. 我将alert语句调试,奇怪的是getData()警报是在回调函数中的警报之前触发的。 Why is this happening? 为什么会这样?

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;
});

...and the strange thing is that the getData() alert is triggered before the alert in the callback function. ...而奇怪的是,在回调函数中的警报之前触发了getData()警报。 Why is this happening? 为什么会这样?

Because ajax calls in general are, by default, asynchronous — and JSONP calls are always asynchronous by their nature (other kinds of ajax calls can be made synchronous, but it's generally a bad idea). 因为默认情况下ajax调用是异步的 - 而且JSONP调用本质上总是异步的(其他类型的ajax调用可以同步,但通常是个坏主意)。

This means your 这意味着你的

var stuff= dataStore.getData();

line executes before the JSONP request completes. line在JSONP请求完成之前执行。 This is also why it doesn't see anything in jsonData . 这也是它在jsonData不到任何内容的jsonData

You need to move any processing of the JSONP call result into something called from the success callback of the request. 您需要将JSONP调用结果的任何处理移动到从请求的success回调调用的内容中。

The problem is that stuff is undefined when $.each runs because stuff hasn't finished running yet. 问题是当$.each运行时, stuffundefined ,因为stuff还没有运行完毕。 Everything needs to be in a callback. 一切都需要回调。 There's numerous ways to get around it from the most ugly and hacky of doing a setInterval() that checks if stuff === undefined and if NOT then it does the $.each to a more JS native way of just using callbacks. 有很多方法可以解决这个问题,从最丑陋的hacky做一个setInterval()来检查是否有stuff === undefined ,如果没有,那么它会将$.each用于更简单地使用回调的JS本机方式。

Personally, I highly suggest you just use callbacks more effectively. 就个人而言,我强烈建议您更有效地使用回调。 Here's what i'd do. 这就是我要做的。 This should put you on the right track. 这应该会让你走上正轨。 Obviously a lot of this is faux code, but can easily be modified to your needs. 显然,很多这是人工码,但很容易根据您的需求进行修改。

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()
      }
    });
  }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM