检查返回的JSON的值并更新为false

时间:2017-02-27 02:10:50

标签: javascript jquery

我有一个从外部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()在这种情况下做什么?

1 个答案:

答案 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

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

&#13;
&#13;
function callCallback(callback){
	callback();
}

callCallback(function(){
	console.log('Callback');
});
console.log('Script end');
&#13;
&#13;
&#13;

将产生:

Callback
Script end

第二个:

&#13;
&#13;
function callCallback(callback){
	setTimeout(callback, 0);
}

callCallback(function(){
	console.log('Callback');
});
console.log('Script end');
&#13;
&#13;
&#13;

输出与我的getJSON示例相同,所以:

Script end
Callback

因为即使是零超时,回调函数也会添加到事件队列中,因此不会立即执行。

编辑:此外,getJSON是异步函数,因此它会在获取数据后调用其回调函数,因此无论如何都会在以后执行回调,即使它没有添加到事件队列中。