如何在一个main函数中使用两个getJSON调用?

时间:2017-09-25 03:59:53

标签: javascript jquery

我当前的<body>...<script>....</script></body>标签包含以下内容:

<script>

$(document).ready(function(){
    function main(){

        var urlOne = 'https:....';
        var summaryTable = {};
        var distinctKeys = [];
        $.getJSON(urlOne, function(jsonOne) {
            // write code to collect data from urlOne and put it in 'summaryTable' AND 'distinctKeys'
            distinctKeys.append(jsonOne['something']);
        }); // end of first getJSON

        /* ****** the javascript would NOT execute anything below this **** */
        var foo = distinctKeys.length;
        for (var i = 0; i < foo; i++) {

            var curUrl = urlConstant + distinctKeys[i];
            $.getJSON(curUrl, function(jsonTwo) {
                // do stuff to add more info into 'summaryTable'
            }); // end of second getJSON

        }; // end of for loop

    }; // end of main()
    main();
}); // end of all javascript code    
</script>

正如我上面提到的,代码不会继续执行/* ****** the javascript would NOT execute anything below this **** */行以下的任何内容。我注意到,distinctKeyssummaryTable在执行第一个$.getJSON调用后仍然为空。我想以特定的顺序拨打getJSON两次 - 第二次是根据第一次通话中获得/收集的信息。谁能解释我怎么能做到这一点?

先谢谢您的回答!

2 个答案:

答案 0 :(得分:1)

您可以使用解决方案

var urlArray = ['https://one.com', 'https://two.com', 'https://three.com'];
var i = 0;

var getJSONData = function(){
  $.getJSON(urlArray[i], function(data){
    console.log(data);   

    i++;
    if( i < urlArray.length)
      getJSONData();
  });

};

您的语法错误var urlArray = ['https://one.com', 'https://two.com', 'https://three.com];,错过了single quote

我建议不要在getJSON中使用for loop方法,而是将其置于方法&amp;一旦从AJAX调用和getting the url's use a variable收到数据,就调用该方法。

根据更新的问题更新了答案

$(document).ready(function(){
  function main(){
    var urlOne = 'https:....';
    var summaryTable = {};
    var distinctKeys = [];
    var i = 0;
    $.getJSON(urlOne, function(jsonOne) {
      // write code to collect data from urlOne and put it in 'summaryTable' AND 'distinctKeys'
      distinctKeys.append(jsonOne['something']);
      getJSONData();  // this will be used to call for the first time.
    }); // end of first getJSON

    var getJSONData = function(){
      var curUrl = urlConstant + distinctKeys[i];
      $.getJSON(curUrl, function(data){
        console.log(data);   
        i++;
        if( i < distinctKeys.length)
          getJSONData();
      });
    };

  }; // end of main()
  main();
}); // end of all javascript code    

希望这会对你有所帮助。

答案 1 :(得分:1)

  

Javascript中的异步函数不会阻止代码   执行。它允许程序流进入下一个语句   不立即执行功能块内部的操作。什么时候   它有一些响应,异步调用内部的函数得到   执行。因此名称callback起作用。

在您的情况下,function(jsonOne) {是一个回调函数,在您从服务器获得响应后执行该函数。

以上陈述的一个小例子:

var data = [];
$.getJSON('https://adobe.github.io/Spry/data/json/array-01.js', function(data) {
    console.log("JSON output length is", data.length);
});
console.log("JSON output length is", data.length);

执行此操作将首先记录JSON output length is 0,然后记录JSON output length is 5。这解释了Javascript如何处理异步调用。

还要注意,我们在回调外访问的数据变量与我们在回调内访问的数据变量不同。回调内的变量数据只能在回调内访问,因为Javascript变量具有功能范围。它们的范围仅限于声明它们的功能。

下一个问题是使用for循环调用异步函数。到目前为止,很明显,即使在第一次getJSON调用得到响应之前,for循环也会完成执行。

  

因此,如果您计划在响应回调中使用i的值,   您将始终获得所有getJSON的终止值   回应回调。

示例代码:

for (var i=0; i<5; i++) {
    $.getJSON('https://adobe.github.io/Spry/data/json/array-01.js', function(jsonData) {
        console.log("Iteration number", i);
    });
}

输出将记录Iteration number 5所有5次迭代。这是因为你的for循环甚至在第一次调用getJSON之前就调用了5 getJSON。

解决方案是利用Javascript的功能范围。

for (var i=0; i<5; i++) {
    (function(x) {
        $.getJSON('https://adobe.github.io/Spry/data/json/array-01.js', function(jsonData) {
            console.log("Iteration number", x);
        });
    )(i);
}

这可以在javascript中使用immediately invoked anonymous functions。基本上在循环中,您调用函数而不是直接调用getJSON。对于此函数,您将i作为参数传递。在函数内部,我可以作为x访问。在函数内部,调用函数时i的值保留为x。

  

对于专家Javascript Ninjas,我更喜欢匿名函数,因为   我不想通过声明一个函数来污染全局命名空间   这个不重复的任务。我知道效率会受到打击但是它会受到影响   对于少数我来说应该没问题。

@ user1330974:这可能不是您期望的直接答案,但一旦您理解了这个概念,您就可以自己解决问题。