2015-03-31 2 views
1

Мне было интересно, есть ли способ вытащить и использовать данные JSON из двух разных источников. В настоящее время код выглядит следующим образом:Как вытащить данные JSON из двух разных источников?

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

}); 

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

}); 

Когда я делаю это, я, кажется, что переменные, созданные из одной функции JSON не доступны в другой, что делает его трудно для них, чтобы быть полезными вместе. Есть ли лучший способ совместной работы этих двух?

+2

Ajax является асинхронным. есть ** НЕТ ** гарантия того, в какой порядок поступят ответы на два вызова, или если они вообще войдут. ваш ответ 'url2' может наступить через 0,03 секунды после того, как вы произнесете вызов, а ответ« url »может появиться через 2 часа, что означает, что код url2 не может ничего делать с переменными url1, потому что они не будут доступны для другого 2 часа. –

ответ

0

Переменная, объявленная внутри функций с использованием var (или блоков, с использованием let) не доступны за пределами функций (или блоки).

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

}); 

Так что, если вы хотите, переменные, которые доступны за пределами области видимости функции они объявлены, вы должны объявить их вне функции они используются.

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

}); 

Как Marc B говорит, что нет способа узнать, какой порядок будет изменен, переменная combined_stuff, либо на JSON1, либо на JSON2 сначала или только один, если один из вызовов getJSON терпит неудачу или ни один из них не будет работать.

Если порядок обновления важен, вызовите тот, который вы хотите использовать вторым, в функции того, который вы хотите вызвать первым.

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

Хорошо, что имеет смысл. Единственная проблема в том, что по какой-то причине, даже если я объявляю переменные за пределами двух json-функций, они по какой-то причине недоступны вне двух (в пределах $ (document.ready())), даже если запись для отображения значения переменной после всего этого кода (undefined). – Antny

+0

Я не знаю формы вашего кода, поэтому я не могу сказать вам точно. Это по-прежнему похоже на проблему с областью (попытка доступа к переменной за пределами области, в которой она объявлена) или проблема с синхронизацией (асинхронный вызов не завершается до вызова предупреждения). –

0

легко с помощью jinqJs с открытым исходным кодом проекта (http://www.jinqJs.com)

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

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

На примере делает синхронизации вызова, вы можете сделать вызов асинхронной делать что-то вроде этого:

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

Результат будет содержать оба результата объединены.

0

Если вы контролируете конечную точку, вы можете заставить ее вернуть все данные, которые вы хотите одним выстрелом. Тогда ваши данные будут выглядеть следующим образом:

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

Если у вас есть 2 конечные точки, нужно ударить, вы можете передать результат первого АЯКС вызова второй функции (но это делает ваш 2 Ajax звонки синхронно):

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

Эта функция принимает массив адресов и функцию обратного вызова в качестве параметров:

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

Вы бы использовать его как это:

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

Вы можете добавить тайм-аут, как функция никогда не вызовет вашего обработчика, если какой-либо из URL-адресов не будет загружен

0

Я бы порекомендовал вам используйте функцию $ .when, доступную в jquery, чтобы выполнить оба метода параллельно, а затем выполнить действие.Смотрите код отрезал ниже,

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>

0

возвращаемых данные от каждого вызова AJAX не доступен за пределами своей собственной функции обратного вызова. Я уверен, что есть более элегантные (сложные?) Решения, но несколько простых, Оккумических решений включают глобальные переменные или хранение полученных данных в скрытых элементах ввода.

В пределах каждой функции обратного вызова, просто цикл, пока данные из другого вызова присутствует:

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