开发者

Iterate on array, calling $.ajax for each element. Return array with all ajax results

I've just started working with JavaScript for non-trivial things, so this is probably straightforward...

What I'm trying to accomplish: iterate on an array of product references, fetch the JSON for each reference, and return an array of all the product information (with a hash-like structure indexed by reference).

What I've tried:

function fetchProductData(references){
  var product_data = new Object();
  references.forEach(function(ref){
    $.ajax({
      url: "http://localhost:3000/products/find.js?reference=" + ref,
      dataType: "jsonp",
      type: "GET",
      processData: false,
      contentType: "application/json",
      success: function(data) {
        product_data[ref] = data;
      }
    });
  });
  alert('before return: ' + product_data);
  return product_data;
};

$(document).ready(function(){
  var products = fetchProductData(references);
  alert('products : ' + products);
开发者_高级运维});

Here's what I don't understand: the first time I call alert to display the array contents, the array is empty. However, on the second call, the array is populated with the data I want.

In other words, the "products :" alert displays the data I want in the code above. But if I comment the "before return: " alert, it no longer does. Why is this?

So my question is: how can I have jQuery make several $.ajax call to fetch product information, collect that information in an array, and return that array so I can use it elsewhere in my code?

Also, why is the data in the variable magically accessible after it is referenced in an alert?


The "A" in "AJAX" stands for "asynchronous" :). Your program doesn't wait for the call to complete before going on to the next iteration, meaning you'll probably not get all of your data. Also the alert has the same problem. Operation to concat 'before return:' to the string add just enough time to get some data in the variable. On a faster machine you might find you never get data.

I think you really need to rethink your approach. It's not a good idea to have multiple AJAX requests in a loop. It will greatly increase latency of the page. Pass all your parameters once using JSON, then have your server side script loop through that and return a single response in JSON.

function fetchProductData(references){
  // make sure your "references" is a JSON object
  $.getJSON('http://server/side/url', {'json':references}, function(product_data) {
      // do something with product_data (alert them, put them in an array, etc)

  });
}


function fetchProductData(references, cb){
  var length = 0;
  var product_data = new Object();
  references.forEach(function(ref){
    length++;
    $.ajax({
      url: "http://localhost:3000/products/find.js?reference=" + ref,
      dataType: "jsonp",
      type: "GET",
      processData: false,
      contentType: "application/json",
      success: function(data) {
        product_data[ref] = data;
        if (++count === length) {
          cb(product_data);
        }
      }
    });
  });

};

$(document).ready(function(){
  var products = fetchProductData(references, function(products) {
    alert('products : ' + products);
  });
});

Use a callback on your asynchronous operation.

The reason it appears to work with the alert call is because alerting a message gives ajax enough time to populate your array. The return statement is only triggered after you click OK on the alert box giving your code a window of 250ms to populate the array with data.


You are executing you ajax query in async mode. And you want a sync result. Try to add:

async: false

Hope this helps.


your $.ajax call is asynchronous, so what is happening is that the first time you make the call, your javascript makes the call, moves on to the next line (alert) and then loops. You're data hasn't returned at that point yet. What you can do to remedy this is to set the async: false option in your $.ajax call.


This is an asynchronous operation. The only sure way to know when the data is ready is in the callback function: success: function () {...}, which gets called when the data has finally returned. Put your alert in there.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜