简体   繁体   中英

How to pull JSON data from two different sources?

I was wondering if there is a way to pull and use JSON data from two different sources. Currently, the code looks like this:

//JSON1
$.getJSON('url1',function(data){
    $.each(data,function(key,val){
        //code
    });

});

//JSON2
$.getJSON('url2',function(data){
    $.each(data,function(key,val){
        //code
    });

});

When I do this, i seems that variables created from one JSON function aren't available in the other one, which makes it hard for them to be useful together. Is there a better way to have these two work together?

This function takes an array of urls and a callback as parameters:

function getMultiJSON(urlList,callback) {
  var respList = {};
  var doneCount = 0;

  for(var x = 0; x < urlList.length; x++) {
    (function(url){
      $.getJSON(url,function(data){
          respList[url] = data;
          doneCount++;

          if(doneCount === urlList.length) {
            callback(respList);
          }
      });

    })(urlList[x]);
  }
}

You would use it like this:

getMultiJSON(['url1','url2'],function(response) {

     // in this case response would have 2 properties,
     //
     // response.url1  data for url1
     // response.url2  data for url2

     // continue logic here
});

You might want to add a timeout as the function will never call your handler should any of the URLs fail to load

Easily using the open source project jinqJs ( http://www.jinqJs.com )

var data1 = jinqJs().from('http://....').select();
var data2 = jinqJs().from('http://....').select();

var result = jinqJs().from(data1, data2).select();

The example does a sync call, you can do an async call by doing something like this:

var data1 = null;
jinqJs().from('http://....', function(self){ data1 = self.select(); });

Result will contain both results combined.

If you control the endpoint, you could make it return all of the data you want in one shot. Then your data would look like:

{
    "url1_data": url1_json_data,
    "url2_data": url2_json_data
}

If you still have 2 endpoints you need to hit, you can pass the result of your first ajax call to the second function (but this makes your 2 ajax calls synchronous):

function getJson1(){
    $.getJSON('url1',function(data){
        getJson2(data);
    });
}
function getJson2(json1Data){
    $.getJSON('url2',function(data){
        //Do stuff with json1 and json2 data
    });
}
getJson1();

Variable declared within the functions using var (or blocks, using let ) are not available outside of the functions (or blocks).

$.getJSON('url1',function(data){
    $.each(data,function(key,val){
        var only_accessible_here = key;
    });

});

So if you want variables that are accessible outside the scope of the function they are declared in, you need to declare them outside of the function they are used in.

var combined_stuff = ''

$.getJSON('url1',function(data){
    $.each(data,function(key,val){
        combined_stuff += val;
    });

});

//JSON2
$.getJSON('url2',function(data){
    $.each(data,function(key,val){
         combined_stuff += val;
    });

});

As Marc B says, there is no way to know which order the combined_stuff variable will be updated, either by JSON1 first, or by JSON2 first, or by only one, if one of the getJSON calls fail, or by neither if both fail.

If the order of updating is important, call the one you want to use second in the function of the one you want to call first.

var combined_stuff = ''

$.getJSON('url1',function(data){
    $.each(data,function(key,val){
        combined_stuff += val;

        //JSON2
        $.getJSON('url2',function(data){
            $.each(data,function(key,val){
                 combined_stuff += val;
            });
        });
    });
});

I would recommend you to use $.when function available in jquery to execute both the methods in parallel and then take the action. See the code snipped below,

 var json1 = [], json2 = []; $.when(GetJson1(), GetJson2()).always(function () { //this code will execute only after getjson1 and getjson2 methods are run executed if (json1.length > 0) { $.each(json1,function(key,val){ //code }); } if (json2.length > 0) { $.each(json2,function(key,val){ //code }); } }); function GetJson1() { return $.ajax({ url: 'url1', type: 'GET', dataType: 'json', success: function (data, textStatus, xhr) { if (data != null) { json1 = data; } }, error: function (xhr, textStatus, errorThrown) { json1 = [];//just initialize to avoid js error } } function GetJson2() { return $.ajax({ url: 'url2', type: 'GET', dataType: 'json', success: function (data, textStatus, xhr) { if (data != null) { json2 = data; } }, error: function (xhr, textStatus, errorThrown) { json2 = [];//just initialize to avoid js error } } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 

The returned data from each AJAX call are not available outside its own callback function. I'm sure there are more elegant (complex?) solutions, but a couple of simple, Occamic, solutions include global variables, or storing the received data in hidden input elements.

Within each callback function, just loop until the data from the other call is present:

function getJson1(){
    $.getJSON('url1',function(data){
        var d2 = '';
        $('#hidden1').val(data);
        while ( d2 == '' ){
            //you should use a time delay here
            d2 = $('#hidden2').val();
        }
        getJson2();
    });
}
function getJson2(){
    $.getJSON('url2',function(d2){
        var d1 = '';
        $('#hidden2').val(d2);
        while ( d1 == '' ){
            //you should use a time delay here
            d1 = $('#hidden1').val();
        }
        //Do stuff with json1 and json2 data
    });
}
getJson1();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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