我有一个从外部API获取问题的函数。我需要在数组中至少有5个问题才能使我的应用程序正常运行。
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,如果是,我将从网址中获取新资源。我将新值保存到数组中,然后它将检查这个新值的数组长度。我希望它继续获取数据,直到条件为真。
发生的事情是,一旦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 :(得分:0)
Edit2 :我举例说明了你的两个函数看起来像是有效的回调循环,两个函数都是相似的,所以它只能是一个函数:
我已经简化了我的脚本和测试我使我的testResponse php脚本返回4个元素[&#34; 1&#34;,&#34; 2&#34;,&#34; 3&#34;,&# 34; 4&#34;]数组几次,最后它返回5个元素[&#34; 1&#34;,&#34; 2&#34;,&#34; 3&#34;,&#34; 4&# 34;,&#34; 5&#34;]数组。
function getCategoryQuestions(callback){
$.getJSON('http://localhost/testResponse.php', function(data){
if(data.questions.length < 5){
getCategoryQuestions(callback);
} else {
callback(data.questions);
}
});
}
代码将从url获取json,如果questions数组小于5,它将再次请求url,直到数组中有5个或更多问题。
如果数组中有5个或更多的问题,它不会再次执行,它将调用带有问题数组作为参数的回调。
这就是你如何使用函数和接收器你的问题数组:
getCategoryQuestions(function(questions){
console.log(questions);
});
还有更多工作要做,比如ajax错误处理。
编辑: getJSON是异步函数,因此它会在获取数据后调用其回调函数,因此无论如何都会在稍后执行回调,即使它没有添加到事件队列中。 / p>
这是因为getJSON成功回调函数执行被添加到事件队列中,并且在console.log之后执行你的array.length
我做了一个测试:
<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){
callback();
}
callCallback(function(){
console.log('Callback');
});
console.log('Script end');
&#13;
将产生:
Callback
Script end
第二个:
function callCallback(callback){
setTimeout(callback, 0);
}
callCallback(function(){
console.log('Callback');
});
console.log('Script end');
&#13;
输出与我的getJSON示例相同,所以:
Script end
Callback
因为即使是零超时,回调函数也会添加到事件队列中,因此不会立即执行。
编辑:此外,getJSON是异步函数,因此它会在获取数据后调用其回调函数,因此无论如何都会在以后执行回调,即使它没有添加到事件队列中。