2017-02-27 45 views
0

我有获取从外部API问题的功能。我需要在数组中至少有5个问题才能运行我的应用程序。检查返回的JSON的价值和更新,如果假

function getCategoryQuestions(){ 
    var questions = {}; 
    var i = 0; 
    for (i; i < 6; i++){ 
    $.getJSON(makeURL(), function(data){ 
     data = data.category; 
     questions[data.name] = data.questions; 
     validQuestionsLength(questions, data.questions) 
    }) 

    } 
    return questions; 
} 

我运行validQuestionsLength,以检查是否每个问题阵列在长度为至少5个元素。

function validQuestionsLength(hash, array){ 
    while (array.length < 5) { 
    $.getJSON(makeURL(), function(data){ 
     data = data.category; 
     hash[data.name] = data.questions 
     array = data.questions; 
    }) 
    console.log(array.length) 
    } 
} 

我想检查一个数组的长度是否小于5,如果是的话我会从url中获取一个新的资源。我将把新的值保存到数组中,然后它会检查这个新值的数组长度。我希望它保持获取数据,直到条件成立。

发生了什么事是,一旦validQuestionsLength()方法运行和我有一个数组长度与小于5时,它保持在console.logging无限循环当前阵列。我以为我在每个循环中保存了一个新的资源。

我不知道在我的逻辑错误发生。

我知道有发生如此前的数组变量被复位的console.log可能运行的异步请求。我编辑我的验证功能,包括做回调执行一次异步完成

function validQuestionsLength(hash, array){ 

    if (array.length < 5) { 
    $.getJSON(makeURL(), function(data){ 
     data = data.category; 
     hash[data.name] = data.questions 

     console.log("data is ", data.questions) 
     array = data.questions; 
    }).done(console.log("array is ", array)) 
    } 
} 

我的目的是向新取的数据保存到数组。但data.questions和数组(它应该指向data.questions的值)是不同的值。 .done()在这种情况下做什么?

+0

那么你的电话一次还是N还是一个问题?您是否在查找所有data.name条目中的每个data.name五个或五个总数?现在你拥有数组的方式会被每次调用覆盖,所以除非你的api调用返回五个项目,否则你将永远循环。 – Michael

+0

使用'array.push(data.questions)'而不是'array = data.questions;'我不知道你的Json结构,你可能需要在其中添加一些索引,比如'questions [0]'或者其他东西 – Viney

+0

你'重新设置完成回调函数错误,您需要将代码嵌入到lambda函数中,以便成功回调,现在您将console.log的设置结果作为** done **事件的回调。所以它现在仍然在回调之前执行。 –

回答

0

EDIT2:我做例子,说明你的两个功能,可以看作为有效的回调循环,两者的功能是相似的,所以它可以只是一个功能:

我已经简化我的剧本和测试,我做了我的testResponse php脚本几次返回4个元素[“1”,“2”,“3”,“4”]数组,最后返回5个元素[“1”,“2”,“3”,“4” “5”]数组。

function getCategoryQuestions(callback){ 
    $.getJSON('http://localhost/testResponse.php', function(data){    
     if(data.questions.length < 5){ 
      getCategoryQuestions(callback); 
     } else {      
      callback(data.questions); 
     } 
    }); 
} 

代码将从URL获得JSON,如果问题数组是小于5它将再次请求URL,直到将有数组5个或更多的问题。

如果将有数组不会再执行自己5个或更多的问题,它会调用与问题数组作为参数的回调。

这是你如何使用功能和接收您的问题阵列:

getCategoryQuestions(function(questions){ 
    console.log(questions); 
}); 

还有更多的工作要做,如AJAX错误处理。

编辑: getJSON是异步funciton,所以它会在获取数据后调用它的回调函数,所以即使它没有被添加到事件队列中,以后的回调也会被执行。

这是因为成功的getJSON回调函数的执行被添加到事件队列,并执行你CONSOLE.LOG阵列后。长度

我做了一个试验:

<html> 
    <head> 
     <script 
      src="https://code.jquery.com/jquery-2.2.4.min.js" 
      integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" 
      crossorigin="anonymous"></script> 
    </head> 
    <body> 
     <script> 
      $.getJSON('http://localhost/testResponse.php', function(data){ 
       console.log('Callback'); 
      }); 
      console.log('Script end'); 
     </script> 
     Hello! 
    </body> 
</html> 

而结果在控制台是:

Script end 
Callback 

为了进一步解释如何发生我将提供两个例子 第一示例:

function callCallback(callback){ 
 
\t callback(); 
 
} 
 

 
callCallback(function(){ 
 
\t console.log('Callback'); 
 
}); 
 
console.log('Script end');

会产生:

Callback 
Script end 

,第二个:

function callCallback(callback){ 
 
\t setTimeout(callback, 0); 
 
} 
 

 
callCallback(function(){ 
 
\t console.log('Callback'); 
 
}); 
 
console.log('Script end');

输出将同我的getJSON例子,所以:

Script end 
Callback 

这是因为即使thare为零超时,回调函数被添加到事件队列,所以它不会立即执行。

编辑:同样的getJSON是异步功能可按所以它会调用回调函数后,将取回的数据,所以回调以后不会被执行,即使是不添加到事件队列。